Zum Hauptinhalt springen

Blöcke und Partituren

Was ein Block ausführt

Veröffentlichungsdatum

22. September 2026

TippIn einem Satz

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

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"]

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

  1. Die Artefaktart timeline ist in ai_query.pipeline.artifact deklariert und hat keinen eigenen Builder. Eine Wahl von timeline fällt auf markdown.
  2. duckdb-read und artifact:<kind> sind adapter-lokale Schritte in famulus_notebook.ops. Sie stehen nicht als Partituren im Register.

5 Festlegungen

  1. Ein Famulus Notebook ist ein Quarto-Notebook. Die ausführbare Einheit ist ein Block, ein Codeblock der Sprache famulus.
  2. 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.
  3. Ein Block trägt genau eines von subtask und partiturs. subtask lädt ai-query-phase1 und übergibt die Instruktion als goal. partiturs ist eine Kette eigener Läufe.
  4. Fehlt client, setzt der Adapter kein Modell. Der Harness nimmt default_model().
  5. 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.
  6. Das Artefakt liegt unter artefacts/ der aktuellen Version des Blocks. Die Trace liegt als trace.json im selben Versionsordner. Ein späterer Block nennt das Artefakt als ref: <id>.<name>.
  7. duckdb nennt die PDAI-Datenbanken des Blocks. Verbindungen bleiben kurzlebig und lesend. evidence nennt grounding, secondary oder both.
  8. oracle prüft das Vertragsergebnis; golden nennt die Golden-Zeile, aus der das Oracle stammt. Der Vergleich steht in verdict.json. Ein leeres Ergebnis bei unaufgelöstem Verweis, ungemounteter Sammlung oder unbekanntem Subtask ist ein Fehler, kein bestandener Lauf.