Write documentation¶
How a page on this site is written. Follow it for every change to any tab.
Where the site lives¶
The site is its own repository, nerthus.docs:
docs/ holds the Markdown, zensical.toml the nav and the theme, data/nerthus.yml the Jinja
variables, ci/ the checks. It documents the whole estate. Code repositories hold no hand-written
explanation: every design note, how-to and runbook about their code is a page here, and the code
cites it by URL. A page's path is therefore an address other repositories depend on; move one only
with the code change that repoints its citations.
Two truths, kept apart¶
The site describes two systems and never mixes them on one page.
-
Nerthus.Core runs today. Every page about it is in the tab Nerthus.Core (until cutover), which is deleted at cutover. Each such page opens, directly under its title, with this line and nothing else in its place:
> **Nerthus.Core (until cutover).** This page describes the frozen system that runs today and is deleted at cutover. Replaced by: …The line ends with a link to the page that replaces it, with
not yet written., or withnone, retired with Core.A Core page is not rewritten: only that line and a dead link change. - The estate is what replaces it. Every other tab describes Platform, Config, the corpora and the regime. A page here says what exists today and what is ruled and not built, and never describes the second as if it ran.
A sentence that describes Core as if it were the estate, or the estate as if it ran today, is the defect to remove. When in doubt, the page goes under the Core tab with the line.
The tabs and their readers¶
| Tab | The reader | Holds |
|---|---|---|
| Start here | anyone, before they know which tab is theirs | the front page, the ecosystem map, the glossary |
| Contributors | changes Platform, Config or this site | the regime, the programmes' history, each repository's pages |
| Hosting | runs an instance or changes the estate's declared resources | a Platform site, Config's plans, the runbooks |
| Nerthus.Core (until cutover) | uses or keeps today's tools | every Core-era page, in its old sections |
Pick the tab by who has to do the thing on the page, not by its subject. Within a section, order is reading order: a page comes after the pages it assumes.
Pages for narrators and players are written in Polish, for someone who writes Markdown and runs no command: an example they could paste first, the explanation after, one idea per sentence, and everything needed to finish the task on the one page. Pages for contributors and hosts are written in English and give exact shapes: commands, file formats, settings, refusals.
Words¶
Everything the estate names is English; Polish is the language it shows to narrators and players. The glossary is the one table of both, and it is generated:
GLOSSARY.md lives in the workspace beside the checkouts. To change a word, change a row there and
regenerate the page in the same merge request; never edit docs/glossary.md by hand.
- Write the English canonical: session, character, player, skill points, Council, vault, site, host, instance. Give the Polish label beside it where a reader will meet the Polish on a screen or in the lore.
- Quote the lore's own grammar exactly as a narrator types it: its paths (
Postaci/,Lokacje/), its tag keys (@należy_do,@lokacja) and therepozytorium-*names are the world's words, not the estate's. - A word in the glossary's retired table is not written outside the Core tab.
No history in a page¶
A page states what is true now. It carries no dates of past events, no task or project ids, no «used to», no story of how a number was measured, and no argument for a decision. A rule is stated as a rule; its ruling number may follow as a citation. How something came to be is the workspace ledger's and git's to record.
Dates and ids inside an example, such as a sample commit message or a pinned value, are part of the example and stay.
One concept, one page¶
Every concept has one page that owns it. Another page states it in at most one sentence and links there. A page that restates another in full is the defect, because the two drift.
A page generated from a source opens with <!-- generated by <command> --> and is regenerated,
never edited. The glossary is one; reference pages for routes, commands and errors will be generated
from each repository's contracts.
Links and addresses¶
- Link between pages by relative path to the
.mdfile:[The database](../explanation/platform/database.md). - An address
data/nerthus.ymlholds is written as its variable ({{ lore.url }}), never pasted: an undefined variable fails the build, a pasted address rots unseen. - An example that needs literal double braces wraps them in a Jinja
rawblock.
The checks¶
Every merge request builds the site with zensical build --strict and runs the jobs
Nerthus.Docs lists. Two of them bind every page:
nav-coverage: every page is in the nav, so no page is published where no reader can reach it.addresses: an address the variables file holds is not hand-typed, in prose or in an example.
Build and run the checks locally before you push:
pip install -r requirements.txt
zensical build --strict
for c in ci/assert-*.py; do python3 "$c" || break; done
ci/assert-merge-request-lane.py takes the CI file as its argument (.gitlab-ci.yml).