- ontology/know.yaml: 49 Klassen, 66 Beziehungen, 12 Vokabulare (72 Konzepte); erzeugt: know.ttl (OWL + SKOS), Ansicht aus viewer.html.tmpl - knaster.ontology: Modell + Prüfung, Export, Momentaufnahme der n8n-Workflows (nur GET; KNOW-Spezifikation aus dem Workflow-Code, Aufrufe inkl. Laufzeit- Operationen, direktes SQL), Abgleich, Übernahme von Entscheidungen - Service-Routine Schritt 8: Verstöße als Befunde, Ontologie-Änderungen als Vorschläge ontology_change (immer Freigabe); „ordne P-x <konzept> zu“; Entscheidungen in ontology_decisions, `knaster ontology apply` schreibt sie in die YAML (Version +1) - CLI: knaster ontology validate|export|snapshot|check|apply; knaster validate prüft Modell und Aktualität der Turtle-Datei - Gegen echten n8n-Export geprüft: neue Befunde B31–B33 (verified/confirmed, KAN ruft unbekannte Operation, MPA ordnet Projektereignisse nie ein) - SPEC-ontology, BETRIEB §6, Router-Image enthält die Ontologie Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.7 KiB
SPEC-ontology: Ontologie der Datenhaltung
Paket: knaster.ontology. Quelle: ontology/know.yaml. CLI: knaster ontology ….
Die Ontologie beschreibt, was in der Datenhaltung steht (Projekt, Kontakt, Ankaufsfall, Mail …) und wie die Begriffe zusammenhängen. Tabellen sind nur die Ablage dahinter. Sie ist die eine Quelle der Wahrheit; Turtle, Graph und Ansicht werden daraus erzeugt, nie von Hand gepflegt.
1. Drei Ebenen, drei Pflegeregeln
| Ebene | Inhalt in know.yaml |
Wie sie sich ändert |
|---|---|---|
| Kern | classes, relations, modules |
bewusst, per Commit (Review wie Code) |
| Vokabulare | vocabularies.*.concepts, alt, rejected |
wachsen über Vorschläge der Service-Routine → Freigabe → knaster ontology apply |
| Instanzen | – (stehen in den Daten) | automatisch; unsichere Verknüpfungen später ebenfalls über Vorschläge |
Ohne diese Regeln zerfällt ein Vokabular wieder in mehrere Listen (KNOW-Befund B20). Deshalb legt nie ein Werkzeug oder LLM selbstständig Klassen oder Konzepte an; es schlägt sie vor.
2. Modell (know.yaml)
id: know
version: 3 # steigt bei jeder Übernahme von Entscheidungen
namespace: urn:mygodel:know#
modules: {mail: Mail & Absender, …}
classes:
Mail:
label: Mail
module: mail
table: mail_events # fehlt = implizite Klasse (nur Wert in Spalten) oder externes System
key: message_id
definition: …
sensitive: … # steuert Datenschutz-Regeln (geplant: PSE/lokal)
subclass_of: Dokument # optional
attributes: {message_id: TEXT, …} # Spalten der Tabelle, Abbild des KNOW-Schemas
relations:
- {source: Mail, name: zugeordnetZu, target: Projekt, via: mail_events.assigned_project_key, kind: key}
# kind: key (gemeinsamer Schlüssel) | soft (Wertabgleich) | external (ID in KanBau/SharePoint/M365)
vocabularies:
MailKategorie:
label: Mail-Kategorie
class: MailKategorie # optional: Konzepte sind Ausprägungen dieser Klasse
columns: [mail_events.category, workflow_hints.hint_type, workflow_hint_config.config_key]
concepts:
buchhaltung: {label: Rechnungen, alt: [Buchhaltung]}
default: {label: Standard, technical: true}
rejected: [MPA] # bewusst kein Konzept
ignore: [sql:ASP - Absender-Report:…] # bewusst hingenommene Befunde
Ontology.validate_model() prüft: Module, Oberklassen und Beziehungsenden existieren; jede Tabelle gehört zu höchstens einer Klasse; Vokabel-Spalten existieren als Attribut; kein Name zeigt auf zwei Konzepte; kein verworfener Wert ist zugleich Konzept. knaster validate prüft das in der CI und warnt, wenn know.ttl nicht zur YAML passt.
3. Abgleich mit n8n (check)
Eingabe ist eine Momentaufnahme der n8n-Workflows (build_snapshot, nur GET /api/v1/workflows bzw. eine JSON-Datei):
- KNOW-Spezifikation aus dem Code des KNOW-Workflows: erlaubte Operationen (
const allowed), Schema (CREATE TABLE,ALTER … ADD COLUMN), pro Operation geschriebene Spalten und dabei gesetzte Literale, Seeds (reine Literal-INSERTs). - Aufrufe von KNOW mit Operation und Payload-Ausdruck. Wird die Operation erst zur Laufzeit gesetzt, werden Kandidaten aus den Literalen des Workflows abgeleitet (
inferred). - Direktes SQL: Postgres-Knoten außerhalb von KNOW, die das Schema
knowledgeansprechen.
Ergebnisse (OntologyFinding, sortiert nach Schwere):
| Art | Schwere | Vorschlag? |
|---|---|---|
unmapped_table – Tabelle ohne Klasse |
medium | ja: add_class |
unmapped_column – Spalte ohne Attribut |
low | ja: add_attribute |
vocab_value – Wert in einer Vokabel-Spalte, der kein Konzept ist |
medium (low, wenn nur aus inaktiven Workflows) | ja: aufnehmen, zuordnen oder verwerfen |
unknown_operation – Aufruf einer Operation, die KNOW nicht kennt |
high (aktiv) / low | nein, Befund |
direct_sql – SQL an KNOW vorbei |
medium (schreibend) / low | nein |
missing_table / missing_column – Ontologie verweist auf etwas, das KNOW nicht anlegt |
medium / low | nein |
concept_without_producer – Konzept, das keine feste Zuordnung erzeugt |
info | nein |
no_write_operation / no_active_writer – Klasse ohne Schreibweg |
info | nein |
Werte werden nur aus Schlüsseln der obersten Payload-Ebene gelesen (verschachtelte JSON-Felder gehören zu einer JSON-Spalte). „Fest“ heißt: Literal oder Zuordnungstabelle mit Literal-Rückfall; bei freien Werten (LLM-Ausgabe) trifft die Prüfung keine Aussage. Entschiedene Schlüssel (Tabelle ontology_decisions) und ignore werden übersprungen.
4. Service-Routine und Freigabe
Schritt 8 der Routine (MaintenanceAgent.run_routine) ruft den Abgleich auf, wenn ontology_path existiert und eine Quelle konfiguriert ist (KNASTER_ONTOLOGY_SNAPSHOT oder N8N_HOST + N8N_API_KEY):
- Befunde ohne Vorschlag erscheinen als Zeilen „Ontologie [schwere]: …“ (höchstens
ontology_max_findings, Standard 15). - Befunde mit Vorschlag werden zu Vorschlägen der Art
ontology_change(Richtlinie: immer Freigabe, Risiko niedrig), dedupliziert überontology:<key>. genehmige P-x→ Entscheidungaccept;ordne P-x <konzept> zu→map(Wert wird alternative Schreibweise des Konzepts);lehne P-x ab: …→reject(Wert landet inrejectedbzw. der Schlüssel inignore).- Entscheidungen liegen in
ontology_decisions; ein entschiedener Schlüssel wird nicht erneut vorgeschlagen. knaster ontology applyschreibt offene Entscheidungen inknow.yaml, erhöhtversion, prüft das Ergebnis und markiert die Entscheidungen als übernommen. Danachknaster ontology export --ttl ontology/know.ttlund committen.
Fällt n8n aus, meldet die Routine „Ontologie-Abgleich nicht möglich“ und läuft weiter.
5. CLI
| Befehl | Zweck |
|---|---|
knaster ontology validate |
Modell prüfen |
knaster ontology export --ttl F --graph F --html F |
Turtle (OWL + SKOS), Graph-JSON, eigenständige Ansicht (ontology/viewer.html.tmpl) |
knaster ontology snapshot --out F |
Workflows lesen und speichern (enthält Workflow-Code, nicht committen) |
knaster ontology check [--snapshot F] [--json] |
Abgleich; Exit 1 bei Befunden der Schwere high |
knaster ontology apply [--dry-run] |
freigegebene Entscheidungen übernehmen |
6. Grenzen und nächste Schritte
- Die Prüfung liest Code, keine Daten: ob Tabellen tatsächlich leer sind, zeigt erst eine Zählung in der Datenbank.
- Weiche Bezüge (z. B. Absender ↔ Kontakt) werden noch nicht automatisch als Verknüpfungsvorschläge erzeugt; geplant über Embeddings mit Schwelle (Instanz-Ebene).
- Aus der Ontologie sollen erzeugt werden: Sichten pro Klasse („Projekt 360°“), JSON-Schemas für Skill-Ausgaben, Werkzeugkatalog für Hermes/NEX, Datenschutz-Regeln aus
sensitive.