Files
cluster-knaster/docs/spec/SPEC-ontology.md
rorappandClaude Opus 5.5 9442cc49d1
ci / test (push) Successful in 27s
ontology: Ontologie als Quelle im Repo, Abgleich mit n8n/KNOW in der Service-Routine
- 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>
2026-10-13 02:54:49 +02:00

101 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`)
```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 `knowledge` ansprechen.
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 über `ontology:<key>`.
- `genehmige P-x` → Entscheidung `accept`; `ordne P-x <konzept> zu` → `map` (Wert wird alternative Schreibweise des Konzepts); `lehne P-x ab: …` → `reject` (Wert landet in `rejected` bzw. der Schlüssel in `ignore`).
- Entscheidungen liegen in `ontology_decisions`; ein entschiedener Schlüssel wird nicht erneut vorgeschlagen.
- `knaster ontology apply` schreibt offene Entscheidungen in `know.yaml`, erhöht `version`, prüft das Ergebnis und markiert die Entscheidungen als übernommen. Danach `knaster ontology export --ttl ontology/know.ttl` und 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`.