Skip to content

Documentation standard

Rivet’s documentation target is the ArchWiki: a reader arrives with a specific problem, finds the exact page, and leaves with a command that works. Not a tutorial series, not marketing, not an API dump.

This document is the house style. It is enforceable — a docs review can cite a section number and the author knows what to change.


1. What “ArchWiki quality” actually means

Section titled “1. What “ArchWiki quality” actually means”

It is not a visual style. Four concrete properties, in priority order:

  1. Correct, and dated when it might not be. Every command in the docs is one someone ran. Where behaviour is version-dependent, say which version.
  2. Complete on its own page. A reader on /docs/backends/ should not need to open three other pages to make rclone work. Cross-link for depth, never for prerequisites.
  3. Skimmable to the answer. Descriptive headings, tables over paragraphs, the command before the explanation of the command.
  4. Honest about limits. The ArchWiki’s real distinguishing feature is that it tells you when something is broken, partially supported, or a bad idea. Rivet’s docs must do the same — see §6.

What we explicitly do not copy: the ArchWiki’s density of jargon and its assumption that the reader already knows the ecosystem. Rivet’s audience includes people rebuilding their first Linux box.


Every reference or guide page, in this order:

<title, from frontmatter — never an H1 in the body>
One or two sentences: what this page covers and who needs it.
If there is a prerequisite, link it here and nowhere else.
[Optional: an admonition, if the page has a footgun.]
## First real section

Rules:

  • No H1 in the body. Starlight renders the title from frontmatter; a body H1 produces two titles. sync-docs.mjs strips a leading H1 automatically, but do not rely on that for authored pages.
  • No “Introduction” or “Overview” heading. The opening paragraph is the introduction. A heading for it is a wasted line in the table of contents.
  • Headings are descriptive, not categorical. “Restoring on a different distro” beats “Cross-distro”. The right-hand ToC is a list of questions the page answers.
  • End with next steps when the page is part of a path (install → quickstart → workflow). Reference pages end when they run out of facts.

  • Second person, present tense, active voice. “Rivet refuses”, not “it will be refused by Rivet”.
  • Imperative for instructions. “Run rivet scan”, not “You can run rivet scan” — the reader knows they can.
  • No “simply”, “just”, “easy”, “obviously”. If it were obvious the page would not exist. These words only tell a struggling reader they are stupid.
  • No filler transitions. “Now that we have configured the backend, let’s move on to…” — delete it and keep the heading.
  • Explain why, once, where a decision looks arbitrary. Rivet refuses to capture SSH keys; the reader deserves the one sentence of reasoning, not a bare prohibition.

The single highest-value rule in this document: a reader must be able to tell what they type from what they get.

Use console with a $ prompt when showing output:

```console
$ rivet status --repo ~/rivet-snapshots
M .config/hypr/hyprland.conf
A .config/kitty/kitty.conf
```

Use sh with no prompt when the block is meant to be copied and run:

```sh
rivet init --repo ~/rivet-snapshots
rivet snapshot --repo ~/rivet-snapshots --push
```

Never mix the two. Never put $ in a sh block — it breaks copy-paste, which is the entire point of the block.

Further rules:

  • Always tag the language. sh, console, toml, rust, json. An untagged block loses syntax highlighting and Pagefind indexing.
  • Real paths, real output. Placeholder output (...) is acceptable only when the omitted part is genuinely irrelevant; mark it # ....
  • ~/rivet-snapshots is the canonical example repository across all pages. Consistency lets a reader copy from three pages in sequence.
  • Show the safe form first. rivet restore --repo … before rivet restore --repo … --apply --yes, always, in that order.
  • Long flags, never short ones, in documentation. --repo, not -r.

Prefer a table whenever content has more than two parallel items with the same shape — flags, backends, distros, exclusion categories. A five-row table is read in ten seconds; five paragraphs are not read at all.

Use a table for Use prose for
Flags and their effects Reasoning and trade-offs
Comparing backends, distros, stores A single sequential procedure
Anything a reader will scan for one row Anything with a narrative order

Keep cells to one line where possible. A table cell containing three sentences should be a subsection instead.


Starlight syntax:

:::note[Optional title]
:::tip
:::caution
:::danger
Type Use for
note Context a reader can skip without harm
tip A faster or cleaner alternative
caution Something that will surprise or annoy: sudo prompts, missing prerequisites, unsupported combinations
danger Something that destroys data or leaks secrets

The honesty rule. Where Rivet does not do what a reasonable reader would assume, say so on the page where they would assume it — not only in the README’s “Current limits” section. Examples that must stay documented:

  • snapshot --push affects Git only; the other backends already wrote during snapshot.
  • checklist --select’s per-manager toggles cover Pacman, AUR, AppImage, Snap, and Flatpak. APT, DNF, Zypper, XBPS, and Nix are captured by default with no toggle yet.
  • The Repology-derived half of the package map ships empty until a maintainer runs rivet-pkgmap-gen.
  • There is no rivet rollback command; recovery means copying from ~/.local/state/rivet/rollback/ by hand.

A limitation that is embarrassing to document is precisely the one that must be documented. Users find these anyway — the only question is whether they find them from us or from a failed restore.


  • Site-internal: absolute, with trailing slash — /docs/backends/. In files under docs/, write normal relative Markdown links (adr/0002-storage-backends.md); sync-docs.mjs rewrites them.
  • Into the code: link the file, not a line number. Line numbers rot within a commit.
  • Every page links up. A reference page links to the guide that uses it; a guide links to the reference for detail. No page is a dead end.
  • Do not link the same target twice in one section. Once, at first mention.

The content is… It lives in… Published to the site by…
A feature users configure docs/<TOPIC>.md a source entry in web/scripts/docs-manifest.json
A design decision and its trade-offs docs/adr/NNNN-*.md a source entry, under Project
A per-milestone build sheet docs/vN.M-implementation-spec.md not published — a development artefact
Onboarding, quickstart, CLI reference web/src/content/authored/*.md an authored entry
Session handover, working notes, assistant instructions repo root, untracked (see .gitignore) not in the repository at all

The rule behind the table: docs/ is for people who use Rivet, spec files are for people who build it. Mixing the two is how a docs site becomes unreadable.


These are not aspirations; they are the definition of done for a change.

  • A changed flag changes web/src/content/authored/cli.md in the same commit. That file is hand-maintained against crates/rivet-cli/src/main.rs and it is the most drift-prone page on the site. Generating it from clap is tracked as a v0.9 item.
  • A renamed doc updates web/scripts/docs-manifest.json. The sync script exits non-zero on a missing source, so CI catches this — but fix it in the same commit rather than making CI find it.
  • A new user-facing feature ships with its docs page, not a follow-up issue. docs/TRACKING.md shipped inside v0.6; that is the standard.
  • Version-specific claims carry their version. “From v0.6 you can…” is correct; “you can now…” is a landmine for a reader on an older release.

Before merging a docs change:

  • Every command was run, or is copied verbatim from one that was
  • Code blocks are language-tagged, and sh blocks contain no $
  • The safe form of a destructive command appears first
  • No “simply”, “just”, “easy”, “obviously”
  • Headings describe the question answered, not the category
  • Limitations relevant to this page are stated on this page (§6)
  • Links resolve — npm run build in web/ fails loudly if a source is gone
  • The page links somewhere, and something links to it