Famulus-Referenz

Belege mit Adresse, Zitat und Herkunft

Veröffentlichungsdatum

14. Oktober 2026

TippDie Famulus-Referenz in einem Satz

Eine Famulus-Referenz ist eine Referenzdatenquelle, die Famulus Proof als Grundlage für Belege braucht: Jedes Item einer Collection hat eine fr:-Adresse, ein Zitat aus erfassten bibliographischen Daten, eine Herkunftskette und Prüfvermerke, und alles steht in einem DuckLake zu einem benannten Snapshot.

Was eine Famulus-Referenz ist

Eine Collection von PDAI-1 wird zur Famulus-Referenz, wenn jedes ihrer Items (Dokument, Seite, Segment) vier Dinge hat:

Bestandteil Inhalt Tabelle
fr:-Adresse stabile Adresse des Items fr_document, fr_page, fr_segment
Zitat BibTeX, CSL-JSON, Textzitat, Fundstelle; nur aus biblio.xml oder dem Deskriptor fr_citation
Herkunft Schritt, Werkzeug, Modell, Anweisung, sha256 von Eingabe und Ausgabe fr_provenance, fr_source
Prüfvermerk Prüfung, Grad DOCUMENTED / INFERRED / HYPOTHESIS / GAP, Zertifikat fr_validation

Das Paket famulus-reference (pdai/famulus-reference) baut daraus je Collection ein Sammlungsschema im DuckLake pdai-collections/_lake/famulus.ducklake nach dem Schema famulus-reference/1. Die Sidecars einer Collection (*_fql, *_stanza) stehen als Kopie im Schema legacy_<coll>; die Kopie ist bei der Migration auf Gleichheit mit dem Original geprüft (fr_migration_log). Geschrieben wird der DuckLake nur auf mac-studio; alle anderen Rechner lesen ihn schreibgeschützt.

Famulus Proof verwendet die Famulus-Referenz an zwei Stellen: als Quelle der Tabellen, auf die FQL und Zielentfaltung ihre Anfragen stellen (Lake-Modus), und als Auflösung der Adresse eines Belegs (famulus_proof.lake.resolve_fr).

Die fr:-Adresse

fr:<collection>/<doc>[/<pidx:04d>[/<segment>]]
Teil Bedeutung Beispiel
<collection> Name der Collection, zugleich ihr Sammlungsschema hartmann
<doc> Ordner des Dokuments bsb00028171
<pidx> Seitenindex, vierstellig 0137
<segment> Bezeichner des Segments oder s und 8 Hexziffern eines Inhaltshashs print1

fr:hartmann/bsb00028171/0137/print1 bezeichnet das Segment print1 auf Seite 137 des Dokuments bsb00028171 der Collection hartmann. Kürzere Adressen bezeichnen die Seite, das Dokument oder die Collection. Globale Kennungen (URN, ARK, DOI, GND, Signatur, IIIF) stehen nicht in der Adresse, sondern in fr_identifier.

Die Adresse als Clause.address

Eine Klausel der Grundresolution (famulus_proof.resolution.Clause) trägt ihre Fundstelle im Feld address. Für einen Beleg aus einer Famulus-Referenz ist das die fr:-Adresse, unverändert. lake.beleg(adresse) liefert die Felder dafür: label ist das Zitat (oder die Adresse, wenn es keines gibt), excerpt die ersten 400 Zeichen der ersten Textschicht.

from famulus_proof import lake
from famulus_proof.resolution import Clause

b = lake.beleg("fr:hartmann/bsb00028171/0137/print1")
k = Clause(frozenset({(True, "Druck(fr:hartmann/bsb00028171/0137/print1)")}),
           kind="beleg", label=b["label"], address=b["address"], excerpt=b["excerpt"])

beleg() gibt außerdem found und snapshot zurück. Ist found falsch, ist die Klausel kein Beleg; der Aufrufer nimmt sie nicht in die Klauselmenge auf und vermerkt eine Lücke.

Was resolve_fr zurückgibt

famulus_proof.lake.resolve_fr(adresse) liest das Item aus dem DuckLake:

Schlüssel Inhalt
adresse die angefragte fr:-Adresse
found true, wenn der DuckLake das Item oder einen Text dazu hat
item die Zeile aus fr_segment, fr_page oder fr_document, je nach Länge der Adresse
texte Textschichten (ocr, diplomatic, normalised, translation), je mit text und sha256
zitat, bibtex Textzitat und BibTeX des Items oder des nächsten Vorfahren mit erfasstem Zitat
zitiert_als die Adresse, deren Zitat verwendet ist: das Item selbst, wenn es ein eigenes Zitat hat, sonst der nächste Vorfahr mit erfasstem Zitat
luecken Felder, die in den bibliographischen Daten fehlen; ["citation"], wenn kein Zitat erfasst ist
herkunft Schritte der Herkunftskette: Schritt, Werkzeug, Modell, sha256, Datei
snapshot Nummer des DuckLake-Snapshots, zu dem gelesen wurde

Eine unbekannte Adresse ergibt {"found": false, "luecke": …} mit dem Grund (Collection nicht im DuckLake oder Adresse nicht im DuckLake), nie eine leere Antwort, die als Beleg gelesen werden könnte. Eine Zeichenkette, die keine fr:-Adresse ist, ergibt einen ValueError.

Lake-Modus: FAMULUS_LAKE=1

Ohne die Umgebungsvariable lesen alle Verbindungen die Sidecar-Datei wie bisher. Mit FAMULUS_LAKE=1 gilt:

Funktion Verhalten im Lake-Modus
famulus_proof.fql.engine.connect(collection, stanza=…) liest aus dem DuckLake, wenn er eine Kopie der Collection hält
famulus_proof.entfaltung.evidence.connect(collection, stanza=…) ebenso, die Stanza-Tabellen unter stz
famulus_proof.fql.engine.has_sidecar(collection) wahr, wenn Sidecar-Datei oder Kopie im DuckLake vorhanden ist

Die Verbindung ist eine DuckDB im Arbeitsspeicher, an die der DuckLake schreibgeschützt als lk angehängt ist. Die Tabellen fql__<t> und stanza__<t> des Schemas legacy_<coll> erscheinen als Sichten unter ihren ursprünglichen Namen (fq_documents, stz.stz_tokens …). Jede bestehende SQL-Anweisung läuft daher unverändert.

Hält der DuckLake keine Kopie der Collection, oder fehlt der Katalog, verwenden beide connect()-Funktionen die Sidecar-Datei.

Primärer Katalog und Lese-Replik

Der primäre Katalog ist FAMULUS_LAKE_CATALOG oder <collections_root>/_lake/famulus.ducklake. famulus_proof.lake.catalog_path() liest jedoch die Lese-Replik daneben (pdai-collections/_lake/famulus.read.ducklake), wenn sie vorhanden ist. Grund: Eine DuckDB-Katalogdatei ist während eines Schreiblaufs (Export, Migration, Wartung auf mac-studio) für andere Prozesse gesperrt. Jeder Schreiblauf veröffentlicht an seinem Ende eine Kopie des Katalogs als Lese-Replik, durch atomares Umbenennen. Leser werden dadurch nie blockiert und sehen den neuen Stand, sobald der Schreiblauf abgeschlossen ist; bis dahin lesen sie den Stand des vorigen Schreiblaufs.

Lage gelesener Katalog
Lese-Replik vorhanden famulus.read.ducklake
keine Lese-Replik famulus.ducklake
FAMULUS_LAKE_PRIMARY gesetzt (etwa =1) famulus.ducklake, auch wenn eine Lese-Replik vorhanden ist

Die Lese-Replik liegt immer neben dem primären Katalog; ein mit FAMULUS_LAKE_CATALOG gesetzter Katalog x.ducklake hat die Lese-Replik x.read.ducklake.

WarnungVolltextsuche

Die Volltextindizes (fts_main_*) sind nicht Teil des DuckLake. FQL-Formen, die match_bm25 aufrufen, brauchen weiter die Sidecar-Datei.

Zitate werden nicht zusammengesetzt

Ein Zitat stammt nur aus erfassten bibliographischen Daten (biblio.xml oder Deskriptor der Collection). Hat ein Item kein eigenes Zitat, gilt das des nächsten Vorfahren (Seite, Dokument, Collection), und die fr:-Adresse des Items ist die Fundstelle; zitiert_als nennt den Vorfahren. Hat auch kein Vorfahr ein Zitat, setzt weder resolve_fr noch der MCP-Server eines aus Titel, Autor oder Dateinamen zusammen: Das Ergebnis ist eine Lücke (luecken: ["citation"], beim MCP-Server status: "gap"). Einzelne fehlende Felder eines erfassten Zitats stehen ebenso in luecken und werden nicht ergänzt.

Reproduzierbarkeit über den Snapshot

Jede Antwort von resolve_fr, beleg und den Werkzeugen des MCP-Servers nennt den Snapshot des DuckLake, zu dem gelesen wurde. Ein Beleg ist damit relativ zu diesem Snapshot bestimmt: Wer die Begründung später prüft, liest die Tabellen zu demselben Snapshot. Die Wartung (famulus-reference maintain) lässt Snapshots nach sieben Tagen verfallen, ausgenommen die in fr_release festgehaltenen und alle Snapshots, die fr_cite oder fr_bibtex ausgegeben haben.

MCP-Werkzeuge für Begründungsanfragen

Der MCP-Server famulus-reference läuft auf mac-studio, Port 5135. Für die Begründung einer Antwort dienen drei Werkzeuge:

Werkzeug Eingabe Antwort
fr_cite fr:-Adresse, Stil (all, bibtex, csl, text) Zitat, cited_as, Fundstelle, Lücken, Snapshot; status ist ok, ancestor oder gap
fr_trace fr:-Adresse Item, sha256 der Textschichten, Herkunft, Prüfvermerke, Belegqualität (evidence_grade), Zitat, Kennungen, Snapshot
fr_trace_run run_id die gelesenen Items, der Snapshot und die SQL-Anweisungen eines früheren Laufs

fr_cite, fr_bibtex, fr_trace, fr_ground und fr_sql zeichnen jeden Aufruf als Lauf auf (fr_run, fr_run_step) und geben dessen run_id zurück. Eine Begründungsanfrage zu einer früheren Antwort wird mit fr_trace_run(run_id) beantwortet: Sie nennt, welche Items mit welchem Snapshot gelesen wurden. Mit fr_trace auf jedes dieser Items folgt die Herkunft und der Prüfvermerk jedes Belegs.

Weitere Werkzeuge (fr_describe_collection, fr_get_item, fr_get_provenance, fr_ground, fr_sql, fr_snapshot_info …) und die Ernte-Endpunkte (/oai, /jsonld, /iiif, /peers) beschreibt pdai/famulus-reference/README.md. Die Einordnung in die Schichten zeigt die Landkarte.