flowchart LR code["Block"] --> adapter["Adapter"] register["partitur_register.duckdb"] --> adapter adapter --> request["RunRequest"] request --> harness["ExecutionHarness.run"] harness --> conductor["Conductor"] conductor --> logDir["log des Blocks"]
Blöcke und Partituren
Was ein Block ausführt
Ein Famulus Notebook ist ein Quarto-Notebook, dessen ausführbare Einheit ein Block ist: ein Codeblock der Sprache famulus. Die Präambel benennt Subtask oder Partitur, der Harness spielt den Plan, das Log hält Trace und Artefakte.
Dieser Text legt fest, was ein Famulus Notebook ist und welche Dateien eine solche Arbeit enthält. Die Attributliste steht in der Syntax, das Arbeitsverzeichnis in der Projektbeschreibung, vier kurze Arbeiten unter Beispiele.
Der Adapter liest einen Block und führt ihn über ExecutionHarness.run aus. Er liegt im Arbeitsbereich famulus-notebook im Paket famulus_notebook. Der Aufruf ist famulus-notebook run <projekt> oder famulus-notebook refresh <projekt>. Der Viewer läuft mit famulus-notebook serve unter Port 5118. Das Spielen einer Partitur braucht ai-agent-orchestrator und ai-query. Lesen, Anzeigen, Rendern und die adapter-lokalen Schritte duckdb-read und artifact:<kind> brauchen sie nicht, solange der Block kein Oracle trägt.
1 Die Einheit
Eine Partitur ist der deklarative Plan einer Handlung: freie Eingaben, Stufen, ein Vertrag darüber, wann das Ziel erreicht ist. Das Register partitur_register.duckdb hält diese Pläne, geordnet nach goal_path. Das Notebook nennt einen Plan beim Namen. Der Conductor spielt die gebundene Partitur. Das Vertragsergebnis eines Laufs heißt Artefakt. Die Trace, die der Conductor von demselben Lauf schreibt, behält ihren Namen.
Die historische Query-Partitur ai-query-phase1 (goal_path: query/historical/stage-one) bündelt die registrierten Subtasks. Ein Block nennt deshalb entweder einen subtask dieser Partitur oder, in partiturs, eine Kette von Register-Ids. Beides führt der Adapter als ExecutionHarness.run(RunRequest) aus. Die Subtask-Liste und die Attributgruppen stehen in der Syntax.
Vier weitere Arten von Blöcken führt der Harness als Zielentfaltung aus, jede nach einem Protokoll aus famulus-proof (famulus_proof.entfaltung). Jede schreibt neben die Version des Blocks einen Bericht famulus-enfolding/1 (<log>/<block>/enfold/enfolding.json), den die Werkbank mit Entfaltung öffnen zeigt.
| Vorspann | Protokoll | Was der Block prüft |
|---|---|---|
ziel: entfalten |
famulus-zielentfaltung |
eine Frage an eine Korrespondenz: Normalisierung, Evidenzraum, Teilziele nach der Fundlage, Vollständigkeit der Belegliste |
request: true |
famulus-anfrage |
eine FQL-Anfrage mit ihrem Argument |
pruefen: satz mit satz: {paper, hash, text} |
famulus-satz |
einen Satz eines Aufsatzes gegen die Belegbasis des Lektorats |
pruefen: messwert mit aussage: {koerper, objekt, groesse, methode, wert, toleranz} |
famulus-messwert |
eine Messaussage gegen einen Datenbestand mit Deskriptor |
Jedes Urteil gilt relativ zur Version des Belegkörpers (karman-nachlass@158478f66b), und jeder Grund trägt eine Adresse in diesem Körper. Beispiele stehen in hitler.fam und pruefungen.fam.
Die Dateien einer Arbeit liegen im Projekt, einem Ordner. Er enthält die Notebooks *.fam, die Vorgaben famulus.yml, die Settings dieser Arbeit und unter _famulus/ die Versionen jedes Blocks. Die Partituren bleiben im Register.
Zähl-Oracle Pirckheimer, 1520–1530, Golden golden-c782fab71c
Der Block briefpartner-zahl ist die erste Stufe der Beispielarbeit. Die Präambel nennt Sammlung, Jahre, Subtask und das Golden. Die Instruktion nach der schließenden --- ist die Frage.
```{famulus}
---
id: briefpartner-zahl
collections: [pirckheimer]
locked: true
evidence: grounding
years: {from: 1520, to: 1530}
subtask: correspondence-count
golden: golden-c782fab71c
client: gemini-3.5-flash-lite
---
Wie viele Briefpartner hatte Pirckheimer zwischen 1520 und 1530?
```Das Oracle dieser Frage ist 75 verschiedene Briefpartner. In golden_ground steht die Zeile auf candidate. Ein geprüfter Lauf derselben Frage hat den Score 1.000 erreicht. Der Block bindet die Zeile; die Promotion auf golden bleibt ein eigener Schritt des Lernzyklus. Eine Gegenprobe am 23. September 2026 zählt im Register 77 Partner: letters_resolved von pirckheimer, alle 354 Briefe (datiert 1520–1527), verschiedene ent_id des Gegenübers von Willibald Pirckheimer. Die Differenz von zwei Personen ist offen; sie steht unter Abfragen und Lernen.
2 Ausführung
Der Adapter übersetzt jeden Block in einen oder mehrere Aufrufe ExecutionHarness.run. Ein RunRequest trägt eine Partitur. Fehlt client, setzt der Adapter kein Modell: default_model() liest ORCH_PROVIDER, sonst ollama:glm-5.3:cloud (DEFAULT_MODEL in harness/builders.py). Die Tool-Runtimes bleiben dabei unverändert. Query-Blöcke setzen client: gemini-3.5-flash-lite, den Default der Query-Pipeline.
| Attribut | Feld des RunRequest |
|---|---|
id |
goal_id |
client |
model |
| Instruktion | goal und inputs.instruction |
subtask |
Partitur ai-query-phase1, Subtask-Name in inputs.subtask |
partiturs[].id |
Auflösung aus dem Register, dann partitur_path oder das geladene Partitur-Objekt |
partiturs[].setting |
setting |
partiturs[].input |
Einträge in inputs |
collections, locked, reading_doc, person_id, project |
Setting und dieselben Schlüssel in inputs |
log ist kein Feld von RunRequest. Der Adapter schreibt Trace und Artefakte an den Pfad, den log nennt. Die vollständige Abbildung, einschließlich duckdb, evidence und golden, steht in der Syntax.
Der Binder löst freie Eingaben in feststehender Reihenfolge: explizite Bindung aus input, dann die Setting, dann der in der Partitur erklärte Default. Fehlt danach eine erforderliche Eingabe, nennt der Adapter den Namen, schreibt kein Artefakt und beendet die Kette.
Liegen Notebook und Register auf verschiedenen Maschinen, löst der Adapter eine Register-Id über einen MCP-Server auf, der das Register liest. Liegen sie auf derselben Maschine, liest dieselbe Funktion das Register unmittelbar. Beide Wege liefern dasselbe Partitur-Dokument.
Der Normalfall der Instantiierung ist die Maschine, auf der die PDAI-Sammlung liegt. Die Sammlung bleibt auf dieser Maschine. Eine Setting darf eine Runtime nennen.
3 Paket und Querverweis
Jeder Block schreibt seine Versionen in das Projekt. Ein späterer Block nennt ein Artefakt mit ref: <id>.<name>, ein Block eines anderen Projekts mit ref: fam:<projekt>/<notebook>/<id>.<name>. Das ist der Querverweis: das Artefakt eines Laufs ist die Eingabe eines späteren Laufs. Im Fließtext bindet der Shortcode {{< famulus <id> <name> >}} dasselbe Artefakt in die gerenderte Seite ein. Verzeichnis, manifest.json und der Vergleich mit den Rollen eines LaTeX-Projekts stehen in der Projektbeschreibung.
4 Lücken
- Die Artefaktart
timelineist inai_query.pipeline.artifactdeklariert und hat keinen eigenen Builder. Eine Wahl vontimelinefällt aufmarkdown. duckdb-readundartifact:<kind>sind adapter-lokale Schritte infamulus_notebook.ops. Sie stehen nicht als Partituren im Register.
5 Festlegungen
- Ein Famulus Notebook ist ein Quarto-Notebook. Die ausführbare Einheit ist ein Block, ein Codeblock der Sprache
famulus. - Ein Block besteht aus der Präambel zwischen zwei Zeilen
---und der Instruktion danach. Die Präambel nennt den Kontext vollständig. Die YAML-Präambel der.fam-Datei ist die Quarto-Präambel. - Ein Block trägt genau eines von
subtaskundpartiturs.subtasklädtai-query-phase1und übergibt die Instruktion alsgoal.partitursist eine Kette eigener Läufe. - Fehlt
client, setzt der Adapter kein Modell. Der Harness nimmtdefault_model(). - Der Binder bindet in der Reihenfolge explizite Bindung, Setting, Default. Ein Lauf, der das Ziel nicht erreicht, beendet die Kette. Das Log hält die Trace und die benannte Lücke.
- Das Artefakt liegt unter
artefacts/der aktuellen Version des Blocks. Die Trace liegt alstrace.jsonim selben Versionsordner. Ein späterer Block nennt das Artefakt alsref: <id>.<name>. duckdbnennt die PDAI-Datenbanken des Blocks. Verbindungen bleiben kurzlebig und lesend.evidencenenntgrounding,secondaryoderboth.oracleprüft das Vertragsergebnis;goldennennt die Golden-Zeile, aus der das Oracle stammt. Der Vergleich steht inverdict.json. Ein leeres Ergebnis bei unaufgelöstem Verweis, ungemounteter Sammlung oder unbekanntem Subtask ist ein Fehler, kein bestandener Lauf.