Skip to content

Orgabot is in private alpha. Request access, or join our Discord.

← All documentation
Reference

Writing documentation: front matter and markdown

How these pages are built and checked, the front-matter contract and markdown subset, and the rule that a system change carries its doc update with it.

Last updated

The standing rule

An update to the system gets a corresponding documentation update when one applies.

If a change alters behavior an operator relies on (a command, a flag, a default, a failure mode, a governance rule), the same change updates the page that describes it. Documentation that lags the system is worse than absent documentation, because it is confidently wrong.

How a page works

Each page is one markdown file in site/src/content/docs/. The filename is the URL slug: capability-packs.md is served at /docs/capability-packs.

There is no registry to update. src/lib/docs.ts globs the directory at build time, and scripts/routes.mjs reads the same directory, so a new file automatically appears in the sidebar, the search index, sitemap.xml, and the prerender pass. A hand-maintained list is exactly what would leave a new page unindexed.

Front matter

Every file starts with a fenced block. All fields except keywords are required, and the build fails loudly if one is missing or if category is not a known section.

---
title: Capability packs
seoTitle: Capability packs: job training for roles
summary: One sentence that shows on the index card and as the page's meta description.
category: The organization
order: 2
keywords: capability pack, tool slot, knowledge-only
---
FieldMeaning
titleThe short label: sidebar, previous and next links, and the breadcrumb. Also the page heading and document title when there is no seoTitle
seoTitleOptional. The search-facing title: the page's <title>, its H1, and its article headline
summaryIndex card text, the intro line, and the SEO description
categoryOne of: Start here, Using Orgabot, The organization, Reference
orderPosition within the category
keywordsComma-separated search boosts for words that may not appear in the body

Titles

A bare noun such as "Invariants" is a fine sidebar label and a poor search result. When title is a generic noun or shorter than 30 characters, add a seoTitle that says what the page is about, for example Invariants: the safety properties Orgabot enforces. The document title renders as the seoTitle followed by | Orgabot, unless it already names Orgabot, and should stay between 30 and 60 characters so search results do not truncate it. The effective title (seoTitle, or title when there is none) may not be shorter than 30 characters, and the rendered document title may not pass 70.

Summaries

The summary is the meta description, so keep it to 155 characters or fewer (and at least 50), and lead with what the reader gets rather than a list of subtopics. Do not put the product name in it: every document title already ends in the brand, so repeating it spends characters that should describe the page.

The last-updated date is derived, never written

Each page shows a "Last updated" line and publishes the same date as dateModified in its structured data. That date is the date of the last git commit to the markdown file, read at build time. Never write an updated field by hand: the build refuses a page that sets one, because a hand-written date is a claim no commit backs and it goes stale the first time someone edits the page and forgets it.

This is also why the standing rule matters: a page's date only moves when its file is committed, so a behavior change must carry its doc edit in the same PR. A doc updated later, or not at all, publishes a date that says the page is current when it is not.

The markdown subset

Rendering is a small in-repo parser, not a markdown library, and it produces React elements rather than an HTML string, so no page can inject markup and the site's strict script-src 'self' policy needs no exception.

Supported: ##, ### and #### headings; paragraphs; bullet and numbered lists; fenced code blocks; > callouts; pipe tables; standalone images; --- dividers; and, inline, bold with double asterisks, italic with single asterisks, code in single backticks, and links in the ordinary [text](target) form.

Anything outside that subset renders as literal text. Two conventions matter:

  • `##` headings become the page's "On this page" list and its deep-link anchors, so write them as things a reader would search for.
  • Internal links use the site path (/docs/invariants), which keeps navigation client-side. External links open in a new tab automatically.

Screenshots

Put images in site/public/docs/ and reference them by absolute path:

![The Orgabot dashboard, with running missions and the mission terminal](/docs/dashboard-overview.webp)

The alt text doubles as the caption and as search text, so describe what the reader should notice in the image, not just what the image is of. Prefer WebP.

Checks that run

npm test in site/ covers the documentation as content, not just as code:

  • every markdown file parses and carries valid front matter;
  • every summary is between 50 and 155 characters and never names the product;
  • every effective title is at least 30 characters, and no rendered document title passes 70;
  • no front matter sets updated by hand;
  • slugs are unique and categories are known;
  • every internal /docs/... link resolves to a page that exists;
  • every referenced image exists in public/;
  • every doc route appears in the shared ROUTES list, so the sitemap and prerender never drift;
  • the markdown parser and the search ranking have their own unit tests.

Run the site locally with npm run dev (port 3001) and read the page you wrote before shipping it.