famulus.lettre.ai — the public namespace
One domain for every public static page of Famulus: how it is built, published and controlled
In brief
Every public static page of Famulus lives under https://famulus.lettre.ai/. The user-site repository grasshoff/grasshoff.github.io carries the custom domain, so every GitHub Pages repository of the account is served at famulus.lettre.ai/<repository>/: the repository name is the path. Live services (edition readers, the notebook application, the subscribe API) stay on lettre.ngrok.dev; the static pages link to them.
| Path | Content | Built by |
|---|---|---|
/ |
Famulus front page, tool band, links to News, Docs, Editions | landings2026/build/export_site.py |
/notebook/ /proof/ /repro/ /lektor/ |
tool pages (opening of each tool’s documentation) | export_site.py |
/guide/ |
forwards to the guide of the newsletter | export_site.py |
/news/ |
Famulus News (repository news) |
famulus-news export-pages |
/docs/<section>/ |
reader documentation (repository docs) |
landings2026/build/export_docs.py |
/editions/ |
public overview of the portals (repository editions) |
platform/scripts/landings_overview.py |
/euler/ … /kausalitaet/ |
edition portals, one repository each | landings2026/build/export_pages.py and the projects’ own builds |
The address book
platform/config/landings.yaml defines every public address: per landing public, repo (the path) and old_repo (the name before 20 October 2026), and the site: block with the domain, the sections, the tool pages and the documentation sources (selection, exclusions, replacements). The rules that follow from it — old names and their new paths, the rewrite of old addresses, the leak patterns, the list of promised addresses — live in one module, platform/shared/famulus_namespace.py, used by the exporters and by the control. No tool types an address by hand.
Publishing
cd scholarly/projects/landings2026/build
uv run python export_docs.py --push # 1. documentation, leak-gated, writes docs-map.json
uv run python export_site.py --push # 2. front page, tool pages, /guide/, 404 forwarding, CNAME
uv run python export_pages.py <slug> # a portal; then push its repository
cd publication/rundbriefe/famulus-news
uv run famulus-news export-pages --push # the newsletter
platform/.venv/bin/python platform/scripts/landings_overview.py # /editions/ (push scholarly/projects/editions)The documentation export copies only reader documentation, removes the navigation of the platform pages, leaves out pages about machines and devices and the Hevelius notebook (Brepols rights), replaces tailnet addresses, rewrites old grasshoff.github.io addresses and stops before committing when a tailnet host or address, a device id or a key is left. The newsletter’s mails link the public copy (mail.links: pages); publish pushes the copy and waits until the issue answers before it sends.
Control
platform/.venv/bin/ae-platform landings namespace # report; exit 1 on a critical findingIt runs inside the nightly backend control (02:10) as well; its findings join the alert mail and can be acknowledged under known: in config/landing_health.yaml. Report: registry/health/namespace-latest.md.
| Check | What is controlled |
|---|---|
| dns | CNAME famulus → grasshoff.github.io; GitHub’s verification TXT record for lettre.ai |
| pages | the user site carries the domain with HTTPS enforced; every namespace repository publishes and has no domain of its own |
| address | every address of the address book answers 200 with HTML |
| forward | every old grasshoff.github.io/<old>/ redirects to the domain, and the site’s 404 page forwards it to its new path |
| publish | no namespace repository has commits that are not pushed (or is behind GitHub) |
| content | in what is published (HEAD): no old address, no machine data, no link inside the namespace to a missing file |
| legacy | other Pages repositories of the account, served under the domain too (listed, not judged) |
Adding a section
- Create the repository
grasshoff/<path>; Pages frommain, folder/; noCNAMEof its own. - Enter it in
landings.yaml(public,repo,old_repowhen it replaces an address). - Run the control.
Never public
Hevelius (Brepols rights), the draft publications (arxiv, release pending), internal landings (internal: true), the administration part of this documentation.