Contributing to the docs
The documentation site is built from the Markdown files in this directory, in
place. There is nothing to register: write or edit a .md file under docs/,
and it is a page of the site, in the right section of the sidebar, found by the
search. The same files read fine on GitHub.
Preview
make docs-dev # live preview at http://localhost:4321/ichor/next/ (search needs the built site)
make docs-site # the real build of the development docs into site/dist, with the search index
make docs-preview # serve site/dist
make docs-site-all # every version, as published, into site/dist-all
This guide's commands are the one place that assumes the dev shell: run them
inside nix develop, or with the tools from
Before you begin on your PATH.
When you write commands in a page, write them as if the tools are on PATH;
do not put nix develop or nix develop -c in a command block. make docs-site fails on a broken
internal link (a missing file, a missing page or a missing #heading), so a
Markdown-only change cannot publish one.
Versions
You only ever edit the Markdown on main. That is published as the
development docs (/next/, "Unreleased (main)"). Each release tag vX.Y.Z
publishes the docs/ it was tagged with as /vX.Y.Z/, and /latest/ and the
site root lead to the newest release, so a release's docs are frozen by its tag
and nothing is copied. The version menu in the header lists them from
versions.json, which the workflow writes from the tags.
Adding a page
Create docs/<section>/<name>.md, starting with a # Title heading. That is
all that is needed:
- The URL is the path without
.md:docs/guides/rotate-keys.mdis/guides/rotate-keys/.README.mdorindex.mdin a directory is that directory's own page, anddocs/index.mdis the home page. - The section is the directory.
guides/is Guides,design/is Concepts,reference/is Reference andadr/is Decisions (newest first, collapsed until you are in it). Any other directory becomes a section of its own, listed after those; a directory inside a section becomes a collapsible group. - The title is the front matter
title, else the first#heading. The site prints it as the page heading, so the Markdown's own#line is not shown twice. - The headings
##and###make the "On this page" list.
Front matter (optional)
---
title: A title that differs from the first heading
sidebar_label: A shorter name for the sidebar
sidebar_order: 1
---
Without sidebar_order, pages in a section are listed alphabetically by
title. Give a page a number to put it first (lower numbers come first; pages
without one come after). GitHub shows front matter as a small table, so use it
sparingly.
Links and images
Link to other pages the way you would on GitHub, with relative paths:
[Adopt and reclaim](adopt-and-reclaim.md), [the design](../design/architecture.md#trust).
They become site links. A relative link that leaves docs/
(../../internal/foo.go, ../../test/harness/) becomes a link to that file or
directory on GitHub. A link to something that does not exist fails the build.
Images live in docs/images/ and are referenced the same way,
; the site serves the SVG and PNG files of
docs/ at their own path. A missing image fails the build too. Diagrams have
their own section below.
Callouts
Use GitHub's alert syntax; GitHub renders it too, and the site shows it as an alert.
> [!NOTE]
> Something worth knowing.
> [!WARNING]
> Something that can hurt.
The kinds are NOTE, TIP, IMPORTANT, WARNING and CAUTION.
This box is the TIP kind.
Code
Use fenced blocks with a language (```sh, ```yaml, ```go). The site
highlights them (light and dark) and adds a copy button; there is nothing to add
by hand.
Every block must name its language, and make docs-site fails with the file
and line of one that does not. Use sh for shell commands, console for a
session that shows $ prompts with their output, yaml, json and go for
source, and text for plain output, diagrams and file trees. The generated
pages under reference/ are labeled by make docs-reference.
What every page gets
Nothing here is written by hand. Each page has a "Copy page" menu (copy the
Markdown, view it, copy the link, share on devices that can), every ## and
### heading has a link icon that copies the address of that section, and the
Markdown of every page is served as <page>.md next to it, with /llms.txt
(an index) and /llms-full.txt (all pages) for tools that read the docs. The
copied Markdown has its relative links rewritten to full URLs, so it still
works outside the site.
Diagrams
Diagrams are draw.io files in docs/images/, always
a pair:
NAME.light.drawio.svgis the one you edit. It is an ordinary SVG, so GitHub and the site show it as an image, and it carries the whole draw.io model, so draw.io (the web app, the desktop app or the VS Code Draw.io extension) opens it as a diagram.NAME.dark.drawio.svgis the same diagram in the dark theme. It is exported from the light file and never edited by hand.
A page names the light file once, with an alt text that says what the diagram shows and a one-line caption under it:

*A one-line caption.*
GitHub shows the light image. The site shows the dark one when the reader's theme is dark, and each image links to its SVG, which opens at full size (the page column is narrower than the diagram).
To change a diagram, open docs/images/NAME.light.drawio.svg in draw.io, edit
it and save it under the same name, then export the pair again:
make docs-diagrams # every diagram
make docs-diagrams SOURCE=docs/images/NAME.light.drawio.svg # one
make docs-diagrams runs the draw.io command line from the dev shell (under
xvfb-run, as draw.io is an Electron app), once for each theme. A new diagram
is drawn the same way and saved as docs/images/NAME.drawio;
make docs-diagrams SOURCE=docs/images/NAME.drawio writes the pair.
One model gives both files because every colour in it is a light-dark() pair,
which draw.io writes into the shape's style (Edit Style, Ctrl-E in draw.io), for
example fillColor=light-dark(#EEF2FF,#232553);strokeColor=light-dark(#6366F1,#818CF8).
Copy a shape from an existing diagram to keep the look, which is one palette
throughout: neutral grey for boxes and groups, indigo for Ichor's own parts and
for what a person does, amber for what waits or is not authenticated, green for
done and red for no way back. Boxes are rounded, connectors are orthogonal with
labels on the line, text is 12 px or more, and a diagram is about 900 px wide.
The export drops the PNG copies of the labels that draw.io adds for viewers
without foreignObject (700 KB a diagram), as browsers and GitHub draw the live
text.