Docs System
Part of: Dev Docs
How documentation flows from the morph repo to morph.levizr.com, and how to add or fix a page on either track. Yes, the docs system is documented in the docs — someone has to maintain it, and that someone is whoever touches it last. Possibly you. Welcome.
The pipeline
morph repo site repo (morph.levizr.com) browser
────────── ──────────────────────────── ───────
docs/**/*.md ──┐
├─► raw.githubusercontent.com ──► /docs/[...slug] ──► /docs/…
docs/docs.registry.json ─┘ (nav: sections, titles, SEO, dates)
docs/dev/<category>/*.md ──┐
├─► raw.githubusercontent.com ──► /dev/docs/[...slug] ──► /dev/docs/…
docs/dev.registry.json ─┘The site fetches from GitHub main — there is no build-time copy. Pushing to main updates the site (a purge workflow clears the fetch cache per push). Dev pages live one directory per category (architecture/, crates/, morpher/, state/, runtime/, build-cli/, testing/, contributing/, bugs/) mirroring the registry categories. Both tracks share the registry schema: { title, sidebarTitle, slug, file, status, author, description, keywords, lastUpdated, publishedAt, priority, changefreq }.
Two titles per page
Every entry carries both a title and a sidebarTitle, and they do different jobs:
| Field | Job | Example |
|---|---|---|
title |
The page headline and SEO surface — long-tail, what someone types into a search engine | How to Install Morph on Linux |
sidebarTitle |
The human label in every navigation surface — sidebar, prev/next, topic lists, search dropdown | Installation |
Navigation surfaces render sidebarTitle and fall back to title when it's missing, so a registry written before this field existed still works. Keep the short label a bare noun (Installation, Event Handling, mx-export) — it sits in a 240px column and gets truncated. A long-tail title there is the thing this field exists to fix, and readers hover the link to see the full headline. Page headlines keep the long form; that is where it belongs.
The two tracks
User docs (/docs) |
Dev docs (/dev/docs) |
|
|---|---|---|
| Source | docs/ |
docs/dev/<category>/ |
| Registry | docs/docs.registry.json |
docs/dev.registry.json |
| Audience | People building apps | Contributors + the curious |
| Promises | Yes — changes need migration notes | No — internals can change freely |
| URL | /docs/<slug> |
/dev/docs/<slug> |
Adding a page
- Write the
.mdindocs/(user) or in the matchingdocs/dev/<category>/directory (internals — every dev page lives in its category dir, never flat indocs/dev/). - Register it in the matching registry file:
slugis the URL path,fileis the repo path — they don't have to match, but keep them mirrored (slug: architecture/foo↔file: dev/architecture/foo) unless you enjoy confusing the next editor.titleis the SEO headline,sidebarTitleis the one- or two-word nav label (see above) — both, always. New category? Add the directory and the registry category together — one without the other is a page the site can't find or a nav entry pointing at air. BumplastUpdatedon any page you touch. - Link rules:
page.md→ same category;../<category>/<page>.md→ another dev category (e.g.../runtime/networking.md);../../guides/x.mdfrom a dev page →/docs/guides/xautomatically;../../../CONTRIBUTING.md(escaping the docs root) → GitHub blob link automatically. Anchors (#section) survive all of these — use them. - Validate before pushing:
Registry must stay valid JSON, everypython3 -c "import json; json.load(open('docs/dev.registry.json'))"filemust resolve to a real.md, and every relative link must land somewhere. Then push — the site picks it up frommain.
Moving or renaming a page
Moving a file means touching four things, and forgetting any one of them breaks something silently:
- The file itself (
git mvkeeps history — use it for tracked files). - Its
filefield in the registry. - Every link pointing at it (grep the whole
docs/tree —future/andguides/link into dev pages too). - Its
slug, if you want the URL to follow (remember: slug changes break published URLs;filechanges don't).
Styles
- User docs: second person, task-oriented, honest about gaps, email CTA for open ideas (
suggestions.morph@levizr.com). - Dev docs: file references required, decision flows over prose, concepts before mechanics, one worked example minimum, a "where to cut" table, and "verify by" steps for anything load-bearing.
- Neither track uses emojis in prose. Code blocks carry the examples, not adjectives. Funny is welcome; unclear is not — if the joke obscures the mechanism, cut the joke.