ontology: Ontologie als Quelle im Repo, Abgleich mit n8n/KNOW in der Service-Routine
ci / test (push) Successful in 27s

- 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>
This commit is contained in:
2026-10-13 02:54:49 +02:00
co-authored by Claude Opus 5.5
parent 525b29aa6d
commit 9442cc49d1
29 changed files with 3675 additions and 96 deletions
+30
View File
@@ -71,3 +71,33 @@ Freitext, der keinem Befehl entspricht, bildet ein kleines Modell auf einen Befe
| Skill-Stufe | Prompt `stufe <skill> zurück` bzw. Git-Revert der SKILL.md |
| Treiber/Engine | Proxmox-Snapshot der GPU-VM (vor jedem Update anlegen) |
| Konfiguration | Git-Revert und Neustart des Router-Containers |
## 6. Ontologie pflegen
Die Ontologie (`ontology/know.yaml`) beschreibt die Begriffe der Datenhaltung. Details in `docs/spec/SPEC-ontology.md`.
- **Kern** (Klassen, Beziehungen) ändert sich nur per Commit.
- **Vokabulare** wachsen über die Service-Routine. Sie gleicht n8n nur lesend mit der Ontologie ab und schlägt neue Werte vor:
```
> routine
Befunde:
- Ontologie [high]: KAN - Kanbau API Gateway ruft `get_kanbau_project_patterns` auf, die Operation gibt es in KNOW nicht
Offene Vorschläge:
- P-21 [low] Mail-Kategorie: neuer Wert „bauvorhaben“
- P-22 [low] Mail-Kategorie: neuer Wert „MPA“
> genehmige P-21 → neues Konzept
> ordne P-21 sonstiges zu → „bauvorhaben“ wird Schreibweise von „sonstiges“
> lehne P-22 ab: Workflow-Name → Wert wird verworfen und nicht wieder vorgeschlagen
```
Danach im Repo übernehmen, z. B. wöchentlich:
```
knaster ontology apply # Entscheidungen → know.yaml, Version +1
knaster ontology export --ttl ontology/know.ttl
git commit -am "ontology: Entscheidungen übernommen"
```
Ohne `N8N_HOST`/`N8N_API_KEY` (oder `KNASTER_ONTOLOGY_SNAPSHOT`) ist der Abgleich aus. Fällt n8n aus, läuft die Routine weiter und meldet das.
+3 -1
View File
@@ -18,6 +18,7 @@ Vorgehen pro Baustein: **Spec → Implementierung → Tests → Commit**. Bis zu
| 10 | Plattform | ADR-0001/0002 | OpenTofu (bpg/proxmox), Ansible-Rollen (IOMMU/VFIO, ZFS-Replikation, Treiber-Pinning, Xid-Exporter) | ✅ geschrieben, **nicht** gegen echten Cluster/`tofu validate` geprüft |
| 11 | CI | – | Gitea Actions: Tests, Lint, Konfig-Validierung (Runner `gitrunner-knaster`) | ✅ |
| 12 | TTS + Legacy-GPUs | ADR-0006 | Engine-Grenzen im Katalog, deaktivierte GPUs, geteilte GPU-Rollen, TTS-Slots, Piper-Dienst, TTS-Canary, `knaster bench tts` | ✅ |
| 13 | Ontologie der Datenhaltung | SPEC-ontology | `ontology/know.yaml` als Quelle, Export (Turtle/SKOS, Graph, Ansicht), Abgleich mit n8n/KNOW (nur lesend), Vorschläge `ontology_change` in der Service-Routine, `knaster ontology apply` | ✅ gegen echten n8n-Export geprüft (24 Befunde, 4 Vokabel-Vorschläge) |
## Teststrategie
@@ -30,11 +31,12 @@ Vorgehen pro Baustein: **Spec → Implementierung → Tests → Commit**. Bis zu
| Was | Wie geprüft |
|---|---|
| Kernlogik (Router, Eskalation, Verifier, Pflege-Agent, Healer, Lifecycle, Placement) | 136 Unit- und Integrationstests (`make test`) |
| Kernlogik (Router, Eskalation, Verifier, Pflege-Agent, Healer, Lifecycle, Placement) | 152 Unit- und Integrationstests (`make test`) |
| Konfiguration (Registry ↔ Skills ↔ LiteLLM ↔ Healer ↔ Policy ↔ Katalog) | `knaster validate` |
| Compose-Dateien | `docker compose config` (`make compose-check`) |
| Prometheus/Alertmanager/n8n-JSON | Strukturtests (`core/tests/test_artifacts.py`) |
| n8n, Portainer | nur lesender Erreichbarkeitstest, nichts deployt |
| Ontologie ↔ n8n | `knaster ontology check` gegen einen lesend abgerufenen Export aller Workflows (13.10.); Tests mit synthetischen Workflows |
| OpenTofu, Ansible | nur YAML/Syntax. `tofu validate` und `ansible-lint` stehen noch aus |
## Offene Punkte vor dem Deployment
+25 -1
View File
@@ -11,7 +11,7 @@ Jeder Befund wurde am Code nachgeprüft, Artefakte der automatischen Auswertung
- Übersicht der Tabellen: [KNOW-schema.md](KNOW-schema.md)
- Interaktive Ansichten (privat):
- Datenfluss: https://claude.ai/artifact/GP8FfU8M6Wk9hPRmJuk96h
- Ontologie: https://claude.ai/artifact/R7zxBJsCKkkCWdCcztLFUT (OWL/Turtle: [know-ontology.ttl](know-ontology.ttl))
- Ontologie: https://claude.ai/artifact/R7zxBJsCKkkCWdCcztLFUT (Quelle: [ontology/know.yaml](../../ontology/know.yaml))
Status aller Befunde: **offen**. In n8n wurde nichts geändert.
@@ -47,6 +47,9 @@ Status aller Befunde: **offen**. In n8n wurde nichts geändert.
| B28 | Zustand in staticData von 9 Workflows, außerhalb von KNOW | mittel |
| B29 | Browser-Sessions (Cookies, Header) unverschlüsselt gespeichert | hoch (Sicherheit) |
| B30 | LLM-Aufrufe am PSE-LiteLLM vorbei, u. a. Kaufvertragstexte | hoch (Datenschutz) |
| B31 | Zwei Wörter für „bestätigt“: `verified` vs. `confirmed` | niedrig |
| B32 | KAN-Gateway ruft `get_kanbau_project_patterns` auf, die es nicht gibt | hoch |
| B33 | MPA speichert jedes Projektereignis als `info`/`normal` | hoch |
## B1 – CANCEL protokolliert ins Leere
- **Beleg:** `CANCEL - Unsubscribe Link` (aktiv) ruft in 4 Knoten (`KNOW: Log Erfolg`, `… Fehler`, `… Duplikat-Erfolg`, `… Dry Run`) `log_workflow_decision` auf. Diese Operation steht nicht in der Liste von KNOW, KNOW wirft `Nicht erlaubte KNOW operation`. Alle 4 Knoten haben „Continue on Fail“.
@@ -312,3 +315,24 @@ Bei einem vorhandenen Datensatz aktualisieren mehrere Upserts nur wenige Spalten
- KNOW maskiert alle Werte über `sqlString`/`sqlJson`. Bei den Operationen gibt es keine offene String-Verkettung. Die Ausnahme ist der direkte SQL-Knoten in CAT (B4).
- KGW prüft HMAC und Zeitfenster und lässt nur eine feste Liste von Operationen zu.
- Die vermeintlich fehlende Spalte `workflow_decisions.decided_by` existiert (per `ALTER` ergänzt).
---
# Gefunden mit `knaster ontology check` (13.10.)
Diese Befunde hat der automatische Abgleich gefunden, nachdem die Ontologie im Repo als Quelle angelegt war (SPEC-ontology).
### B31 – Zwei Wörter für „bestätigt“
- **Beleg:** `record_workflow_decision` setzt `quality_status` auf `verified`. Alle anderen Tabellen und Operationen nutzen `confirmed`.
- **Folge:** Auswertungen über `quality_status = 'confirmed'` übersehen bestätigte Entscheidungen.
- **Stand in der Ontologie:** `verified` ist als alternative Schreibweise von `confirmed` im Vokabular *Qualitätsstatus* eingetragen. Vorschlag: in KNOW auf `confirmed` vereinheitlichen.
### B32 – KAN-Gateway ruft eine Operation auf, die es nicht gibt
- **Beleg:** `KAN - Kanbau API Gateway` (aktiv) ruft `get_kanbau_project_patterns` auf. Die Operation steht nicht in der Liste von KNOW. Das Gegenstück `upsert_kanbau_project_patterns` in KAN-Learn fehlt ebenso (B2).
- **Folge:** Gelernte Projektmuster für KanBau werden weder gespeichert noch gelesen. Je nach Fehlerbehandlung des Knotens bricht das Gateway an dieser Stelle ab.
- **Vorschlag:** die beiden Operationen samt Zieltabelle in KNOW anlegen (und dann in der Ontologie aufnehmen) oder die Aufrufe entfernen.
### B33 – Projektereignisse ohne Einordnung
- **Beleg:** `MPA - Projekt-Ablage` ruft `upsert_project_event` mit den festen Werten `category: "info"` und `urgency: "normal"` auf.
- **Folge:** Die Ereignisarten `verzoegerung`, `mangel`, `termin` und `kosten` (CHECK-Constraint der Tabelle) kommen nie vor, ebenso keine Dringlichkeit `high`. Eine Auswertung „Mängel pro Projekt“ ist mit diesen Daten nicht möglich.
- **Vorschlag:** Kategorie und Dringlichkeit aus der Mail-Analyse übernehmen (MAIL bzw. CAT kennen „Mangel“) oder ein kleines Modell bzw. einen knaster-Skill einordnen lassen.
+2 -2
View File
@@ -3,9 +3,9 @@
Stand: 13.10.2026. Abgeleitet aus den Workflow-Definitionen auf n8n.mindboost.app, gelesen über die n8n-API. Inhalte der Datenbank wurden nicht gelesen.
Interaktive Ansichten (privat, Freigabe über das Share-Menü):
- Datenfluss: https://claude.ai/artifact/GP8FfU8M6Wk9hPRmJuk96h
- Ontologie: https://claude.ai/artifact/R7zxBJsCKkkCWdCcztLFUT (als OWL/Turtle: [know-ontology.ttl](know-ontology.ttl))
- Ontologie: https://claude.ai/artifact/R7zxBJsCKkkCWdCcztLFUT (Quelle: [ontology/know.yaml](../../ontology/know.yaml), Turtle: [ontology/know.ttl](../../ontology/know.ttl))
Befunde mit Belegen, Folgen und Vorschlägen: [KNOW-befunde.md](KNOW-befunde.md) (B1–B30)
Befunde mit Belegen, Folgen und Vorschlägen: [KNOW-befunde.md](KNOW-befunde.md) (B1–B33)
## Aufbau
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
# 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`.