Projekt
Ordner, Notebooks, Laufablage, Versionen
Ein Projekt ist ein Ordner mit einer Datei famulus.yml und einem oder mehreren Notebooks *.fam; was die Läufe erzeugen, legt der Runner unter _famulus/ ab, jede neue Fassung eines Ergebnisses als eigene Version.
Die Partituren bleiben im Register. Das Projekt führt sie nicht mit.
<projekt>/
famulus.yml Kennung, Titel, Vorgaben, Importe
<notebook>.fam ein Notebook; es darf mehrere geben
kapitel/<teil>.fam Kapitel eines integrierenden Notebooks
settings/<partitur>.setting.yaml
data/ bibliography.bib Hilfsdaten des Autors
famulus.lock gelesene und erzeugte Versionen, vom Runner geschrieben
_famulus/ vom Runner geschrieben, nie von Hand
store/<notebook>/index.json
store/<notebook>/<block>/current.json
store/<notebook>/<block>/v0001/
manifest.json trace.json report.json verdict.json result.json
artefacts/<name>.<ext>
cache/extern/<peer>/… Kopien ferner Artefakte mit Herkunftsangabe
build/<notebook>.qmd Schattenkopie für Quarto
Die Beispielprojekte unter site/projekte/ zeigen diesen Baum für je eine Arbeit; die Leseseiten stehen im Menü Projekte.
1 famulus.yml
id: pirckheimer-briefwechsel
title: Pirckheimers Briefpartner 1520–1530
defaults:
collections: [pirckheimer]
client: gemini-3.5-flash-lite
evidence: grounding
duckdb_root: $PDAI_COLLECTIONS
imports:
kepler: fam:kepler-lex-naturae/lex-naturae
moved:
briefpartner: briefpartner-1520-1530| Schlüssel | Bedeutung |
|---|---|
id |
Kennung des Projekts: Kleinbuchstaben, Ziffern, Bindestrich. Sie steht in jedem Verweis fam:<id>/…. |
title |
Titel im Viewer und in der Navigation |
defaults |
Vorgaben aller Blöcke. Ein Schlüssel in der Präambel eines Blocks ersetzt denselben Schlüssel; Listen werden ersetzt, nicht aneinandergereiht. |
imports |
Kurznamen für Notebooks anderer Projekte, gültig in allen Notebooks dieses Projekts |
moved |
alte Kennung → neue Kennung, für Notebooks (alt: neu) oder Blöcke (nb/alt: nb/neu). Ein Verweis auf den alten Namen wird aufgelöst und als verschoben gemeldet. |
main |
das integrierende Notebook, wenn es mehrere gibt |
duckdb_root ist der Wert, den der Runner für $PDAI_COLLECTIONS einsetzt, wenn die Umgebungsvariable fehlt. Ist weder die Variable noch die Datei vorhanden, ist das ein Fehler der Klasse „Sammlung nicht da“.
2 Notebook
Ein Notebook ist eine Datei <name>.fam: Quarto-Markdown mit Blöcken der Sprache famulus. Die Kennung ist famulus.id in der Präambel, sonst der Dateiname ohne Endung. Der Schlüssel eines Notebooks ist <projekt>/<notebook>; unter diesem Schlüssel adressieren es der Viewer, der Lektor und die HTTP-Schnittstelle.
---
title: Pirckheimers Briefpartner 1520–1530
famulus:
id: briefpartner-1520-1530
uses:
lex: fam:kepler-lex-naturae/lex-naturae@latest
chapters: [kapitel/einleitung.fam, kapitel/zaehlung.fam]
---uses gibt Kurznamen, die nur in diesem Notebook gelten. chapters macht das Notebook zum integrierenden Notebook: die Kapitel sind eigene Notebooks desselben Projekts, das Hauptnotebook nennt ihre Reihenfolge.
Die .fam-Datei ist die einzige Quelle. Quarto sieht sie nie direkt: famulus-notebook build schreibt eine Schattenkopie .qmd mit einem Block famulus-build in der Präambel, der für jeden Block den Ordner der aktuellen Version und für jeden Shortcode die aufgelöste Datei nennt. Die Quarto-Extension liest nur diesen Block. Für die Site liegen die Kopien unter site/lesen/<projekt>/; famulus-notebook render baut sie und rendert dann.
3 Laufablage und Versionen
Jeder Block hat unter _famulus/store/<notebook>/<block>/ eine Folge von Versionen v0001, v0002, … und eine Datei current.json, die auf die aktuelle zeigt. Eine neue Version entsteht nur, wenn sich der Inhalt eines Artefakts ändert. Bringt ein neuer Lauf dasselbe Ergebnis, bleibt die Version; das Manifest zählt dann nur runs hoch.
| Datei | Inhalt |
|---|---|
manifest.json |
input_hash, input_parts, status, version, runs, consumes (gelesene Artefakte mit Version und Prüfsumme), artefacts |
trace.json |
Spur des Laufs, geschrieben aus dem RunResult |
result.json |
Antwort, Urteil, Anzeigeform und herkunft (Partitur, Modell, Sammlungen, Dauer), gelesen vom Viewer |
report.json |
question, answer, verdict, method, counts, findings, by_document, specification, provenance |
verdict.json |
Vergleich mit golden oder oracle: id, golden, status, oracle, observed |
artefacts/<name>.<ext> |
eine Datei je Eintrag von artefacts, mit Kopf famulus |
Der Kopf eines Artefakts sagt, was es ist und woher es kommt. So steht er im Roster des Kármán-Projekts; migrated_from zeigt, dass diese Version aus einem alten Paket übertragen wurde, und input_hash ist der Hash jenes Laufs:
{
"famulus": {
"ref": "fam:karman-nachlass/korrespondenz/karman-roster.roster",
"version": 1,
"sha256": "3e891ae0550d35912026bf59197ff5718c0a9e7d86439a4b0bd02f3208193fec",
"created": "2026-09-23T14:27:05+00:00",
"produced_by": {
"notebook": "karman-nachlass/korrespondenz",
"block": "karman-roster",
"input_hash": "6cf53ffe769935ca",
"migrated_from": ".../site/beispiele/karman-korrespondenz/log/karman-roster"
},
"derived_from": []
},
"data": { "...": "die Nutzlast des Artefakts" }
}Ein neuer Lauf trägt unter produced_by statt migrated_from die Partitur und das Modell ein.
Ein Lauf, der das Ziel nicht erreicht, hinterlässt trace.json und verdict.json mit status: fail oder gap. Die Artefakte der vorigen Version bleiben stehen; die Kette dahinter stoppt.
4 Aktuell, veraltet, wartet
Der Eingabe-Hash eines Blocks setzt sich aus drei Teilen zusammen: Präambel, Instruktion und Vorgaben; die gelesenen Dateien (Größe und Zeitstempel); die Versionen der gelesenen Artefakte. Weicht einer davon vom Manifest ab, ist der Block veraltet, und famulus-notebook status --why nennt den Teil: „Präambel, Instruktion oder Voreinstellungen verändert“, „gelesene Datei verändert“, „Eingaben verändert“. Ein Block, der noch nie lief, fehlt. Ein Block, dessen Vorgänger nicht aktuell ist, wartet. Ein Block mit status: error ist immer veraltet.
rerun in der Präambel entscheidet, was ein Lauf mit einem Block tut:
| Wert | Wirkung |
|---|---|
if-stale (Voreinstellung; if-missing ist dasselbe) |
ausführen, wenn veraltet oder fehlend |
always |
bei jedem Lauf ausführen |
never |
nie von selbst ausführen; nur als veraltet melden |
famulus-notebook refresh <projekt> führt genau die nicht aktuellen Blöcke aus, Erzeuger zuerst. Liest das Projekt ein Artefakt eines anderen lokalen Projekts mit @latest, frischt es dieses Projekt vorher auf. Im Viewer tut der Knopf Aktualisieren dasselbe.
5 famulus.lock
Nach jedem Lauf schreibt der Runner famulus.lock: für jeden Block input_hash, status, version, die gelesenen Artefakte (consumes) und die erzeugten (produces) mit Prüfsumme. Ein Verweis mit dem Wähler @locked liest genau die hier eingetragene Version. So lässt sich ein veröffentlichter Stand wiederholen, auch wenn der Erzeuger inzwischen neuere Versionen hat.
6 Alte Pakete
Ein Ordner mit notebook.qmd und _famulus.yml ist ein altes Paket. Der Runner liest es weiter; seine Läufe liegen unter log/. famulus-notebook project migrate <alt> --id <projekt> --notebook <name> --to <ziel> macht daraus ein Projekt: die Vorgaben wandern nach famulus.yml, das Notebook wird <name>.fam, die letzte Fassung jedes Blocks wird v0001 mit Kopf, und die Prüfsummen bleiben gleich. Die Beispiele dieser Site wurden so übertragen.
7 Rollen
Die Rollen der Dateien entsprechen den Rollen in einem LaTeX-Projekt, und zwar nur als Rollen.
| Datei | Rolle im Famulus-Projekt | Rolle im LaTeX-Projekt |
|---|---|---|
<notebook>.fam |
das Dokument, das der Autor bearbeitet | die Hauptdatei |
kapitel/*.fam |
Kapitel des integrierenden Notebooks | \include-Dateien |
famulus.yml |
Vorgaben und Importe aller Notebooks | die Dokumentklasse, soweit sie Pfade und Sammlung festlegt |
settings/*.setting.yaml |
die Bindung der freien Eingaben | eine Konfigurationsdatei, die das Dokument benennt |
data/, bibliography.bib |
Hilfsdaten und Bibliographie | \input-Dateien und die .bib |
_famulus/store/…/vNNNN/ |
Trace, Bericht, Urteil, Artefakte einer Version | die vom Lauf erzeugten Dateien |
famulus.lock |
welche Version aus welcher entstand | kein Gegenstück; am nächsten kommt eine Paketliste mit Versionen |
| das Partitur-Register, außerhalb des Projekts | die Pläne, die jede Arbeit beim Namen nennt | Dokumentklasse und Pakete, die das Projekt benennt und nicht mitführt |