Implement Phase 3 Agentic Edge Validation and Chunk-Aware Multigraph-System
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 4s
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 4s
- Introduced final validation gate for edges with candidate: prefix. - Enabled automatic generation of mirror edges for explicit connections. - Added support for Note-Scope zones to facilitate global connections. - Enhanced section-based links in the multigraph system for improved edge handling. - Updated documentation and added new ENV variables for configuration. - Ensured no breaking changes for end users, maintaining full backward compatibility.
This commit is contained in:
parent
273c4c6919
commit
39a6998123
1
debug.log
Normal file
1
debug.log
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
[0114/152756.633:ERROR:third_party\crashpad\crashpad\util\win\registration_protocol_win.cc:108] CreateFile: Das System kann die angegebene Datei nicht finden. (0x2)
|
||||||
221
docs/02_concepts/02_concept_kausales_retrieval.md
Normal file
221
docs/02_concepts/02_concept_kausales_retrieval.md
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
<!-- FILE: konzept_zielbild_kausales_retrieval_mindnet.md -->
|
||||||
|
---
|
||||||
|
id: konzept_zielbild_kausales_retrieval_mindnet
|
||||||
|
title: Konzept & Zielbild – Kausalketten-Prüfung und kausales Retrieval für Mindnet (Qdrant)
|
||||||
|
type: concept
|
||||||
|
status: draft
|
||||||
|
created: 2026-01-13
|
||||||
|
lang: de
|
||||||
|
tags:
|
||||||
|
- mindnet
|
||||||
|
- obsidian
|
||||||
|
- knowledge_graph
|
||||||
|
- causal_chains
|
||||||
|
- retrieval
|
||||||
|
---
|
||||||
|
|
||||||
|
# Konzept & Zielbild – Kausalketten-Prüfung und kausales Retrieval für Mindnet (Qdrant)
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
Mindnet soll zu beliebigen Fragestellungen **die richtigen Notizen** nicht nur über semantische Nähe (Embeddings), sondern über **kausale Relevanz** finden.
|
||||||
|
Parallel soll ein Authoring-Assistent helfen, Obsidian-Notizen so anzulegen, dass Kausalketten **formal konsistent** und **traversierbar** sind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ausgangslage / Problem
|
||||||
|
- Der Wissensgraph wird in Qdrant gepflegt; aktuelles Retrieval basiert primär auf **Gewichtung + semantischer Nähe**.
|
||||||
|
- Ergebnis: thematisch nahe Treffer, aber oft **nicht antwortrelevant** (fehlende Ursachen-/Folgenbezüge).
|
||||||
|
- Obsidian-Notizen enthalten Edges (Vorwärts/Rückwärts); Qualität hängt von:
|
||||||
|
- korrekter Relation (Kausalität vs Chronologie),
|
||||||
|
- konsistenten Node-Namen,
|
||||||
|
- Inversen (gegenläufigen Beziehungen),
|
||||||
|
- sauberer Typisierung ab.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Grundannahmen
|
||||||
|
- Viele Antworten benötigen einen **Erklärungspfad** statt eines Einzel-Treffers:
|
||||||
|
- Ursache → Mechanismus/Transformation → Entscheidung → Wirkung → Rückkopplung
|
||||||
|
- Kausalität ist im Graph als gerichtete Kanten modelliert und über inverse Typen **bidirektional navigierbar**:
|
||||||
|
- `resulted_in` ⇄ `caused_by`
|
||||||
|
- `followed_by` ⇄ `preceeded_by`
|
||||||
|
- `derived_from` ⇄ `source_of`
|
||||||
|
- `impacts` ⇄ `impacted_by`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System-Zielbild (2 Hauptkomponenten)
|
||||||
|
|
||||||
|
### 1) Authoring-Assistent (Obsidian Graph Linter + Chain Explorer)
|
||||||
|
Zweck: Qualitätssicherung beim Erstellen/Ändern von Notizen.
|
||||||
|
|
||||||
|
**Kernfunktionen**
|
||||||
|
- **Formale Prüfungen**
|
||||||
|
- Canonical Edge vs Alias (Normalisierung nach `edge_vocabulary`)
|
||||||
|
- Zielnoten existieren / leere Links als `open_question` oder TODO markieren
|
||||||
|
- Tippfehler/Node-Splitting erkennen (mehrere Schreibweisen desselben Knoten)
|
||||||
|
- Edge-Typ zulässig für Note-Typ (z.B. keine Kausal-Edges aus `open_question`)
|
||||||
|
- **Semantische Plausibilität (regelbasiert)**
|
||||||
|
- Chronologie (`followed_by`) ≠ Kausalität (`resulted_in`)
|
||||||
|
- Hub-/Index-Noten nutzen primär `related_to/consists_of` statt Kausalität
|
||||||
|
- Prinzipien bevorzugt `derived_from/based_on` statt pauschal `caused_by`
|
||||||
|
- **Ketten-Integrität**
|
||||||
|
- „Gap“-Warnungen (Sprünge ohne Zwischennoten)
|
||||||
|
- Zyklen ohne Sinn (A caused_by B und B caused_by A)
|
||||||
|
- Mehrfachursachen transparent markieren
|
||||||
|
|
||||||
|
**Outputs**
|
||||||
|
- Lint-Report pro Note (Fehler/Warnung/Empfehlung)
|
||||||
|
- Chain-Preview (2–4 Schritte vorwärts/rückwärts)
|
||||||
|
- Optional: Auto-Fix-Vorschläge (Alias→Canonical, Link-Normalisierung, Inversen ergänzen)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2) Mindnet Retrieval: Hybrid aus Embeddings + Graph Traversal + Reranking
|
||||||
|
Zweck: Aus einer Frage automatisch eine **kleine, kausal zusammenhängende** Menge von Notizen auswählen.
|
||||||
|
|
||||||
|
**Pipeline**
|
||||||
|
1. **Seed Retrieval (Qdrant Embeddings)**
|
||||||
|
- Top-K Kandidaten (z.B. 30) als Startpunkte
|
||||||
|
- Optional: Filter nach Node-Typ (z.B. bei „Welche Entscheidungen…“)
|
||||||
|
|
||||||
|
2. **Intent-Klassifikation (Frage → Richtung & Kettenform)**
|
||||||
|
- Regelbasiert (Start) oder später ML-Classifier
|
||||||
|
- Output: `{direction, preferred_edges, target_types, max_hops, need_explanation_chain}`
|
||||||
|
|
||||||
|
3. **Graph Expansion (Multi-Source Multi-Hop Traversal)**
|
||||||
|
- Expandiert von Seeds 1–3 Hops (typisch 2–4)
|
||||||
|
- Richtungslogik:
|
||||||
|
- „Warum/Ursache“ → rückwärts (`caused_by`, `preceeded_by`, `derived_from`)
|
||||||
|
- „Folgen/Ergebnis“ → vorwärts (`resulted_in`, `followed_by`, `impacts`)
|
||||||
|
- „Entwicklung/Veränderung“ → beides (forward + backward)
|
||||||
|
- Ergebnis: Pfad-Kandidaten (nicht nur Nodes)
|
||||||
|
|
||||||
|
4. **Reranking (Antwortrelevanz)**
|
||||||
|
- Score = Semantik + Pfadqualität + Antwortform-Passung
|
||||||
|
|
||||||
|
5. **Antwort-Bausteine (Minimal Explanation Subgraph)**
|
||||||
|
- Merged Top-Pfade zu einem kleinen Subgraph (z.B. 8–12 Nodes)
|
||||||
|
- Pruning nach zentralen Knoten und erklärender Kettenform
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spezifikation: Intent → Traversal Mode (Heuristik)
|
||||||
|
|
||||||
|
### Intent-Struktur
|
||||||
|
- `direction`: `backward | forward | both`
|
||||||
|
- `preferred_edges`: Menge Edge-Typen
|
||||||
|
- `target_types`: Menge Node-Typen
|
||||||
|
- `max_hops`: int
|
||||||
|
- `need_explanation_chain`: bool
|
||||||
|
|
||||||
|
### Heuristik (Deutsch)
|
||||||
|
- **Warum / Ursache / Auslöser / wodurch / wie kam es dazu**
|
||||||
|
- direction: backward
|
||||||
|
- preferred_edges: `{caused_by, preceeded_by, derived_from}`
|
||||||
|
- target_types: `{experience, decision, strategy, state}`
|
||||||
|
- max_hops: 2–4
|
||||||
|
- **Was führte zu / Folgen / Auswirkungen / resultierte in**
|
||||||
|
- direction: forward
|
||||||
|
- preferred_edges: `{resulted_in, followed_by, impacts}`
|
||||||
|
- target_types: `{decision, strategy, state, principle}`
|
||||||
|
- max_hops: 2–4
|
||||||
|
- **Entwicklung / Veränderung / Weltbild / Glaubenssatz / Charakter**
|
||||||
|
- direction: both
|
||||||
|
- preferred_edges backward: `{caused_by, derived_from}`
|
||||||
|
- preferred_edges forward: `{resulted_in, impacts}`
|
||||||
|
- target_types: `{principle, state, strategy, decision}`
|
||||||
|
- max_hops: 2–4
|
||||||
|
- need_explanation_chain: true
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spezifikation: Traversal (Weighted Multi-Hop)
|
||||||
|
|
||||||
|
### Gewichte (Startwerte)
|
||||||
|
**Edge Weights**
|
||||||
|
- `resulted_in`: 1.00
|
||||||
|
- `caused_by`: 1.00
|
||||||
|
- `derived_from`: 0.90
|
||||||
|
- `source_of`: 0.90
|
||||||
|
- `impacts`: 0.70
|
||||||
|
- `impacted_by`: 0.70
|
||||||
|
- `followed_by`: 0.50
|
||||||
|
- `preceeded_by`: 0.50
|
||||||
|
- `related_to`: 0.25
|
||||||
|
- `part_of/consists_of`: 0.25
|
||||||
|
|
||||||
|
**Node-Type Weights**
|
||||||
|
- `experience`: 1.00
|
||||||
|
- `decision`: 1.00
|
||||||
|
- `strategy`: 0.90
|
||||||
|
- `state`: 0.85
|
||||||
|
- `principle`: 0.85
|
||||||
|
- `insight(hub)`: 0.35
|
||||||
|
- `open_question/hypothesis/white_spot`: 0.00 (Filter)
|
||||||
|
|
||||||
|
**Hop Decay**
|
||||||
|
- `hop_decay(h) = 0.75^h`
|
||||||
|
|
||||||
|
### Traversal-Logik (pseudocode-nah)
|
||||||
|
- Multi-Source-Expansion ab Seeds
|
||||||
|
- Pfade priorisiert nach kumuliertem Pfadscore
|
||||||
|
- `visited` verhindert endlose Wiederholungen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spezifikation: Reranking (Semantik + Kausalität + Antwortform)
|
||||||
|
|
||||||
|
### Final Score
|
||||||
|
- `final_score(path) = alpha*semantic + beta*coherence + gamma*shape_match`
|
||||||
|
|
||||||
|
Startwerte:
|
||||||
|
- `alpha = 0.55` (Semantik)
|
||||||
|
- `beta = 0.30` (Kausal-Kohärenz)
|
||||||
|
- `gamma = 0.15` (Passung zur Frageform)
|
||||||
|
|
||||||
|
**Causal Coherence**
|
||||||
|
- Bonus, wenn Pfad Kausal-Edges enthält (`resulted_in/caused_by/derived_from`)
|
||||||
|
- Malus, wenn nur Navigation/Chronologie enthalten ist
|
||||||
|
- Bonus für Kernform: `experience → decision → (state|strategy|principle)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output: Minimal Explanation Subgraph (MES)
|
||||||
|
Ziel: nicht eine Liste, sondern ein erklärendes Subgraph-Set.
|
||||||
|
|
||||||
|
**Regeln**
|
||||||
|
- Top-Pfade (z.B. 3–5) mergen
|
||||||
|
- max_nodes: 8–12
|
||||||
|
- Pruning:
|
||||||
|
- Hubs raus, wenn sie nur Navigation sind
|
||||||
|
- Decision/Principle/State bevorzugen (Antwortanker)
|
||||||
|
- Bridge-Nodes behalten (in mehreren Pfaden vorkommend)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authoring-Regeln (Graph-Hygiene) – harte Leitplanken
|
||||||
|
1. Kausalität nur auf atomaren Noten (`experience/decision/state/strategy/principle`)
|
||||||
|
2. Hubs/Indexnoten: primär `related_to/consists_of` (keine „Hub verursacht X“-Kausalität)
|
||||||
|
3. Inverse Edges müssen erzeugbar sein (oder Build-Step erzeugt sie deterministisch)
|
||||||
|
4. Chronologie strikt trennen (`followed_by` ≠ `resulted_in`)
|
||||||
|
5. Prinzipien: `derived_from/based_on` für Herkunft (statt pauschal `caused_by`)
|
||||||
|
6. Leere Links als `open_question` oder TODO ohne Kausal-Edge
|
||||||
|
7. Kanonische Dateinamen: Node-Splitting verhindern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Nutzen / Erfolgskriterien
|
||||||
|
- **Bessere Answer Relevance**: Mindnet liefert Knoten mit erklärender Kausalstruktur statt nur thematischer Nähe
|
||||||
|
- **Erklärbarkeit**: Antwort kann mit Pfad(en) begründet werden
|
||||||
|
- **Debuggability**: Fehlantworten lassen sich auf falsche/fehlende Kanten zurückführen
|
||||||
|
- **Authoring-Effizienz**: Assistent verhindert typische Edge-Fehler früh
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Offene Punkte (für nächste Iteration)
|
||||||
|
- Intent-Taxonomie (8–12 Frageklassen) finalisieren und evaluieren
|
||||||
|
- Welche Edges werden als „kausal“ im engeren Sinne akzeptiert?
|
||||||
|
- Welche Node-Typen sind Pflichtmetadaten für Mindnet?
|
||||||
|
- Evaluation: Retrieval-Qualität mit/ohne Traversal (A/B)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
<!-- DOCUMENT 1: pflichtenheft_obsidian_plugin_mindnet_assistant.md -->
|
||||||
|
---
|
||||||
|
id: pflichtenheft_obsidian_plugin_mindnet_assistant
|
||||||
|
title: Pflichtenheft – Obsidian Plugin „Mindnet Causal Assistant“
|
||||||
|
type: specification
|
||||||
|
status: draft
|
||||||
|
created: 2026-01-13
|
||||||
|
lang: de
|
||||||
|
---
|
||||||
|
|
||||||
|
# Pflichtenheft – Obsidian Plugin „Mindnet Causal Assistant“
|
||||||
|
|
||||||
|
## 1. Zielsetzung
|
||||||
|
Das Plugin unterstützt den Nutzer beim Erstellen und Pflegen eines narrativ-kausalen Wissensgraphen in Obsidian (Mindnet).
|
||||||
|
|
||||||
|
Es bietet:
|
||||||
|
- **Aktive Authoring-Unterstützung** (Guided Note Creation / Interview Flow)
|
||||||
|
- **Kausalketten-Prüfung** (Chain Explorer, Vorwärts/Rückwärts)
|
||||||
|
- **Linting + Auto-Fixes** (Graph-Hygiene, konsistente Kanten, Namensnormalisierung)
|
||||||
|
- **Export/Integration** der strukturierten Graph-Daten für ein Retrieval-System (Qdrant + Graph-Index)
|
||||||
|
|
||||||
|
## 2. Kontext & Randbedingungen
|
||||||
|
- Obsidian Vault enthält Notes als Markdown, jede Entität eine Datei.
|
||||||
|
- Notes enthalten Frontmatter (`id,title,type,status,...`) und Edges in Callout-Blöcken.
|
||||||
|
- Edge-Vokabular inklusive Aliasse & Inversen ist verfügbar (z.B. `edge_vocabulary.md`).
|
||||||
|
- Der Graph soll später von Mindnet traversierbar sein (Vorwärts/Rückwärts über inverse Relationen).
|
||||||
|
- Plugin muss offline nutzbar sein; optionale Backend/LLM-Integration ist konfigurierbar.
|
||||||
|
|
||||||
|
## 3. Begriffsdefinitionen
|
||||||
|
- **Node**: eine Obsidian Markdown-Datei (Entität).
|
||||||
|
- **Edge**: gerichtete Beziehung zwischen zwei Nodes (canonical edge type).
|
||||||
|
- **Alias**: alternative Edge-Bezeichnung in Notes, die auf canonical mapped wird.
|
||||||
|
- **Inverse**: Gegenkante zu einer Edge, laut Vokabular (z.B. `resulted_in` ⇄ `caused_by`).
|
||||||
|
- **Hub/Index**: Note, die primär navigiert (typisch `type: insight`), keine Kausalursache.
|
||||||
|
|
||||||
|
## 4. Scope
|
||||||
|
### In Scope (MVP → V2)
|
||||||
|
**MVP**
|
||||||
|
- Parser für Frontmatter + Edge-Callouts
|
||||||
|
- Normalizer: Alias → Canonical; optional Inversen-Erkennung
|
||||||
|
- Linter: Regelset (Error/Warn/Info) + Report
|
||||||
|
- Chain Explorer: forward/backward traversal (1–4 hops) ab aktueller Note
|
||||||
|
- Quickfixes: Edge-Typ ersetzen, Links normalisieren, Missing Note Stub erzeugen
|
||||||
|
|
||||||
|
**V2**
|
||||||
|
- Guided Authoring (Interview Flow) für `experience/decision/principle/state/strategy`
|
||||||
|
- Refactor Mode: Text → Node/Edge-Kandidaten + Review UI
|
||||||
|
- Export/Sync: JSON Graph Export + optional Qdrant Sync (separater Service)
|
||||||
|
|
||||||
|
### Out of Scope (initial)
|
||||||
|
- Vollautomatische Kausalitäts-Interpretation ohne User-Bestätigung
|
||||||
|
- Vollständige UI-Graph-Visualisierung (Obsidian Graph View bleibt nutzbar)
|
||||||
|
- Direkte medizinische/psychologische Beratung
|
||||||
|
|
||||||
|
## 5. Nutzerrollen & Use Cases
|
||||||
|
### Rolle: Nutzer (Author)
|
||||||
|
- UC1: „Ich schreibe eine Note und will Kanten prüfen“
|
||||||
|
- UC2: „Ich will von einem Ereignis aus die Kausalkette sehen“
|
||||||
|
- UC3: „Ich will eine neue Experience/Decision Note sauber anlegen“
|
||||||
|
- UC4: „Ich habe Text und will daraus Kandidaten extrahieren“
|
||||||
|
- UC5: „Ich will leere Links als open_question sauber erzeugen“
|
||||||
|
|
||||||
|
### Rolle: System/Indexer (Mindnet)
|
||||||
|
- UC6: „Ich brauche exportierbare adjacency lists + canonical edges“
|
||||||
|
|
||||||
|
## 6. Funktionale Anforderungen (FR)
|
||||||
|
|
||||||
|
### FR1: Vault Parsing
|
||||||
|
- FR1.1 Parse Frontmatter (YAML): `id,title,type,status,date,tags,...`
|
||||||
|
- FR1.2 Parse Edge-Callouts im Format:
|
||||||
|
- `> [!abstract]- 🕸️ Semantic Mapping`
|
||||||
|
- `>> [!edge] <relation>`
|
||||||
|
- `>> [[target]]`
|
||||||
|
- FR1.3 Extrahiere alle WikiLinks `[[...]]` aus Edge-Blocks
|
||||||
|
- FR1.4 Erkenne Datei-Pfade, Dateinamen und canonical node identifiers (Dateiname ohne `.md`)
|
||||||
|
|
||||||
|
**Output (intern)**
|
||||||
|
```ts
|
||||||
|
type Node = { id?: string; title?: string; type?: string; status?: string; path: string; slug: string };
|
||||||
|
type Edge = { srcSlug: string; dstSlug: string; rawType: string; canonicalType?: string; line?: number; blockId?: string };
|
||||||
|
```
|
||||||
|
|
||||||
|
### FR2: Edge Normalization
|
||||||
|
- FR2.1 Map rawType/Alias auf canonical edge type via Edge Vocabulary
|
||||||
|
- FR2.2 Speichere Mapping-Entscheidungen (raw → canonical) pro Edge
|
||||||
|
- FR2.3 Liefere inverse edge type (`inverseType`) pro canonical edge type (sofern definiert)
|
||||||
|
|
||||||
|
### FR3: Linting
|
||||||
|
- FR3.1 Führe Checkliste von Regeln aus (siehe separates Dokument)
|
||||||
|
- FR3.2 Liefere LintReport mit Severity (ERROR/WARN/INFO), Location (file, line), Fix-Vorschlägen
|
||||||
|
- FR3.3 Quickfix: wende Fix auf Note an (Text edit), mit Preview/Diff
|
||||||
|
|
||||||
|
### FR4: Chain Explorer (Traversal)
|
||||||
|
- FR4.1 Startpunkt: aktuelle Note im Editor
|
||||||
|
- FR4.2 Forward traversal: `resulted_in`, `followed_by`, `impacts`, `source_of`, optional `related_to`
|
||||||
|
- FR4.3 Backward traversal: `caused_by`, `preceeded_by`, `derived_from`, `impacted_by`
|
||||||
|
- FR4.4 Konfigurierbare maxHops (Default 3)
|
||||||
|
- FR4.5 Ergebnis als Liste von Pfaden + kompaktes Subgraph-Summary (Nodes/Edges)
|
||||||
|
|
||||||
|
### FR5: Missing Notes / Stubs
|
||||||
|
- FR5.1 Erkenne, wenn Edge-Target nicht existiert
|
||||||
|
- FR5.2 Biete „Create Stub Note“ an:
|
||||||
|
- Template basierend auf Typ (default `open_question` wenn unbekannt)
|
||||||
|
- Einhaltung Naming-Rules: `a-z0-9_`
|
||||||
|
- FR5.3 Optional: convert TODO-Link → open_question note
|
||||||
|
|
||||||
|
### FR6: Guided Authoring (V2)
|
||||||
|
- FR6.1 Wizard für neue Notes: Auswahl Typ → Fragen (eine nach der anderen)
|
||||||
|
- FR6.2 Wizard erstellt Datei mit Template + initialen Edge-Blocks
|
||||||
|
- FR6.3 Jede automatische Edge-Vermutung ist „review-required“
|
||||||
|
|
||||||
|
### FR7: Refactor Mode (V2)
|
||||||
|
- FR7.1 Extrahiere aus aktuellem Note-Text Kandidaten:
|
||||||
|
- Event-Kandidaten (Datum/Ort/Verben)
|
||||||
|
- Decision-Kandidaten („entschied“, „nahm an“, „wechselte“)
|
||||||
|
- Principle-Kandidaten („ich glaube“, „ich habe gelernt“)
|
||||||
|
- Relation-Kandidaten („dadurch“, „führte zu“, „weil“)
|
||||||
|
- FR7.2 UI-Review: Checkbox-Liste zum Erstellen/Verwerfen
|
||||||
|
- FR7.3 Generiere Notes + Edges nur nach Bestätigung
|
||||||
|
|
||||||
|
### FR8: Export (MVP optional / V2 empfohlen)
|
||||||
|
- FR8.1 Export JSON: Nodes + canonical edges + inverses
|
||||||
|
- FR8.2 Export adjacency list pro node slug
|
||||||
|
- FR8.3 Optional: webhook/CLI hook für Indexer (Qdrant)
|
||||||
|
|
||||||
|
## 7. Nicht-funktionale Anforderungen (NFR)
|
||||||
|
- NFR1: Performant bei 10k Notes (incremental parse, caching)
|
||||||
|
- NFR2: Offline-first; LLM/Backend optional
|
||||||
|
- NFR3: Deterministische Normalisierung (gleiches Input → gleiches Output)
|
||||||
|
- NFR4: Kein Erfinden von Fakten: Auto-Edge nur als Vorschlag
|
||||||
|
- NFR5: Sicheres Editieren (Diff/Undo via Obsidian APIs)
|
||||||
|
- NFR6: Konfigurierbarkeit (YAML/Settings Tab): maxHops, allowed edges, strict mode
|
||||||
|
|
||||||
|
## 8. Technisches Lösungsdesign
|
||||||
|
|
||||||
|
### 8.1 Obsidian Plugin Struktur (TypeScript)
|
||||||
|
- `main.ts` – Plugin lifecycle, commands, views
|
||||||
|
- `settings.ts` – Einstellungen
|
||||||
|
- `parser/` – Markdown + callout parser
|
||||||
|
- `graph/` – Node/Edge model, normalization, traversal
|
||||||
|
- `lint/` – Rules engine, reports, quickfixes
|
||||||
|
- `ui/` – Sidebar view, modals, diff preview
|
||||||
|
|
||||||
|
### 8.2 Speicherung / Cache
|
||||||
|
- In-memory cache: map `path → parsed Node + edges + hash`
|
||||||
|
- Incremental update: on file change events re-parse only changed file
|
||||||
|
- Optional persisted cache in `.obsidian/plugins/.../cache.json`
|
||||||
|
|
||||||
|
### 8.3 Edge Vocabulary Integration
|
||||||
|
- Input: `edge_vocabulary.md` im Vault ODER eingebettete JSON Ressource
|
||||||
|
- Parsing:
|
||||||
|
- canonical edge types
|
||||||
|
- alias list
|
||||||
|
- inverse mapping
|
||||||
|
- Fallback: minimal builtin vocabulary, wenn Datei fehlt
|
||||||
|
|
||||||
|
### 8.4 Traversal Engine
|
||||||
|
- Graph Index: adjacency lists aus canonical edges
|
||||||
|
- Traversal:
|
||||||
|
- BFS mit hop limit
|
||||||
|
- optional weighted expansion (für Chain Explorer „relevant paths first“)
|
||||||
|
|
||||||
|
### 8.5 Quickfix Engine
|
||||||
|
- Applies patches auf Markdown:
|
||||||
|
- Replace edge type token im Callout (`>> [!edge] ...`)
|
||||||
|
- Rename link targets (replace `[[old]]` → `[[new]]`)
|
||||||
|
- Insert stub note file from template
|
||||||
|
- Safety:
|
||||||
|
- Show diff modal
|
||||||
|
- Use Obsidian editor transactions / file API
|
||||||
|
|
||||||
|
### 8.6 Optional Backend / LLM (V2)
|
||||||
|
- Backend (local node service) für:
|
||||||
|
- text extraction (Refactor Mode)
|
||||||
|
- suggestion generation
|
||||||
|
- Communication:
|
||||||
|
- HTTP local (`127.0.0.1`) oder WebSocket
|
||||||
|
- API key storage via Obsidian settings (encrypted if possible)
|
||||||
|
- Claude-code/Cursor: nutzt Code-Agent für Implementierung, nicht zur Runtime.
|
||||||
|
|
||||||
|
## 9. UI/UX Anforderungen
|
||||||
|
|
||||||
|
### 9.1 Sidebar View „Mindnet Assistant“
|
||||||
|
Tabs:
|
||||||
|
- **Validate**: Lint Report + Fix Buttons
|
||||||
|
- **Chains**: Forward/Backward Chain Explorer + Copy as text
|
||||||
|
- **Create** (V2): Wizard new note
|
||||||
|
- **Refactor** (V2): Extract candidates
|
||||||
|
|
||||||
|
### 9.2 Commands (Command Palette)
|
||||||
|
- `Mindnet: Validate current note`
|
||||||
|
- `Mindnet: Validate vault (selected folders)`
|
||||||
|
- `Mindnet: Show chains from current note`
|
||||||
|
- `Mindnet: Normalize edges in current note`
|
||||||
|
- `Mindnet: Create stub for missing links`
|
||||||
|
- (V2) `Mindnet: Start guided authoring`
|
||||||
|
- (V2) `Mindnet: Refactor current note to graph`
|
||||||
|
|
||||||
|
## 10. Akzeptanzkriterien
|
||||||
|
- AK1: Plugin erkennt Edge-Callouts und normalisiert Aliasse deterministisch
|
||||||
|
- AK2: Linter findet Node-Splitting (mindestens Levenshtein/ähnliche Slugs) und Missing Notes
|
||||||
|
- AK3: Chain Explorer liefert identische Pfade vorwärts/rückwärts bei inversen Edge-Paaren
|
||||||
|
- AK4: Quickfix ersetzt Edge-Typen ohne Markdown zu zerstören; Undo funktioniert
|
||||||
|
- AK5: Export JSON enthält canonical edges + inverse types
|
||||||
|
|
||||||
|
## 11. Deliverables
|
||||||
|
- Obsidian Plugin (TS) mit MVP Features
|
||||||
|
- Dokumentation:
|
||||||
|
- Install/Build
|
||||||
|
- Settings
|
||||||
|
- Rule reference
|
||||||
|
- Example vault sample
|
||||||
|
- Optional: JSON Export Format Spec (nodes/edges)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Prompts für Code-Agenten (Cursor / Claude-code)
|
||||||
|
|
||||||
|
### Prompt A (Repo Scaffold + MVP)
|
||||||
|
> Du bist ein Senior TypeScript Engineer. Implementiere ein Obsidian Plugin „Mindnet Causal Assistant“.
|
||||||
|
> Ziele MVP:
|
||||||
|
> 1) Parse Frontmatter (YAML) und Edge-Callouts im Format:
|
||||||
|
> `> [!abstract]- 🕸️ Semantic Mapping` → `>> [!edge] <relation>` → `>> [[target]]`.
|
||||||
|
> 2) Normalisiere Edge Aliasse auf canonical edge types (Vokabular als JSON im Code; später ersetzbar).
|
||||||
|
> 3) Baue eine Sidebar View mit Tabs „Validate“ und „Chains“.
|
||||||
|
> 4) Implementiere Lint Regeln: missing target note, alias-not-normalized, hub-has-causal-edge, chronology-vs-causality warning.
|
||||||
|
> 5) Implementiere Chain Explorer (forward/backward, maxHops=3).
|
||||||
|
> 6) Implementiere Quickfix: replace edge type token, create stub note.
|
||||||
|
> Nutze Obsidian APIs, schreibe sauberen TS Code, mit Tests für Parser/Normalizer.
|
||||||
|
|
||||||
|
### Prompt B (Parser Unit Tests)
|
||||||
|
> Schreibe Unit Tests für den Markdown Parser:
|
||||||
|
> - erkennt mehrere Edge-Blocks pro Datei
|
||||||
|
> - erkennt mehrere Targets pro Edge
|
||||||
|
> - liefert line numbers
|
||||||
|
> - ignoriert WikiLinks außerhalb der Semantic Mapping Callouts
|
||||||
|
> Nutze vitest/jest. Erzeuge fixtures.
|
||||||
|
|
||||||
|
### Prompt C (Lint Engine + Quickfix)
|
||||||
|
> Implementiere eine Lint Engine als Rule-Pipeline.
|
||||||
|
> Jede Regel: id, severity, detect(node, graph) -> findings, fix(finding)->patch.
|
||||||
|
> Baue eine Diff Preview Modal und applyPatch über Obsidian file API.
|
||||||
|
> Implementiere zunächst 6 Regeln aus der Checkliste.
|
||||||
|
|
||||||
|
### Prompt D (Vocabulary Loader)
|
||||||
|
> Implementiere einen VocabularyLoader:
|
||||||
|
> - lädt entweder eingebettetes JSON oder eine Vault-Datei `edge_vocabulary.md`
|
||||||
|
> - parst canonical types, aliases, inverse
|
||||||
|
> - bietet getCanonical(raw) und getInverse(canonical)
|
||||||
|
> Fallback auf builtin vocabulary wenn parsing fehlschlägt.
|
||||||
136
docs/05_Development/Obsidian/lint_regeln_Kausalität.md
Normal file
136
docs/05_Development/Obsidian/lint_regeln_Kausalität.md
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
<!-- DOCUMENT 2: checklist_lint_regeln_mindnet_assistant.md -->
|
||||||
|
---
|
||||||
|
id: checklist_lint_regeln_mindnet_assistant
|
||||||
|
title: Checkliste – Lint-Regeln für Mindnet Causal Assistant
|
||||||
|
type: specification
|
||||||
|
status: draft
|
||||||
|
created: 2026-01-13
|
||||||
|
lang: de
|
||||||
|
---
|
||||||
|
|
||||||
|
# Checkliste – Lint-Regeln für Mindnet Causal Assistant
|
||||||
|
|
||||||
|
## Severity Levels
|
||||||
|
- **ERROR**: bricht Traversal/Indexer oder erzeugt falsche Nodes
|
||||||
|
- **WARN**: wahrscheinlich falsche Semantik / schlechter Retrieval-Impact
|
||||||
|
- **INFO**: Optimierung / Empfehlung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## A. Graph-Integrität & Naming
|
||||||
|
|
||||||
|
### L1 (ERROR) Missing Target Note
|
||||||
|
**Wenn:** Edge target `[[X]]` existiert nicht als Datei im Vault
|
||||||
|
**Dann:** Finding `missing_target`
|
||||||
|
**Fix:** „Create Stub Note“ (default `type: open_question`) oder remove edge
|
||||||
|
|
||||||
|
### L2 (ERROR) Node Splitting durch Schreibvarianten
|
||||||
|
**Wenn:** mehrere Targets im Vault sind ähnlich (slug distance), oder in Edges mehrere Varianten vorkommen
|
||||||
|
**Dann:** Finding `node_split_candidate`
|
||||||
|
**Fix:** Vorschlag canonical slug + bulk replace links
|
||||||
|
|
||||||
|
### L3 (ERROR) Invalid Filename Policy
|
||||||
|
**Wenn:** Dateiname enthält Zeichen außerhalb `[a-z0-9_]`
|
||||||
|
**Dann:** Finding `invalid_filename`
|
||||||
|
**Fix:** Rename file + update all backlinks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## B. Edge-Formale Regeln
|
||||||
|
|
||||||
|
### L4 (ERROR) Unknown Edge Type / Unmapped Alias
|
||||||
|
**Wenn:** raw edge type nicht im Vokabular (alias→canonical)
|
||||||
|
**Dann:** Finding `unknown_edge_type`
|
||||||
|
**Fix:** Edge type ersetzen durch best guess oder user selection
|
||||||
|
|
||||||
|
### L5 (WARN) Alias not normalized
|
||||||
|
**Wenn:** raw edge type ist Alias, canonical bekannt, aber Note enthält Alias
|
||||||
|
**Dann:** Finding `alias_not_normalized`
|
||||||
|
**Fix:** Replace raw with canonical (optional config)
|
||||||
|
|
||||||
|
### L6 (WARN) Missing Inverse Edge (optional strict mode)
|
||||||
|
**Wenn:** Edge A->B existiert, inverse nach Vokabular fehlt in B
|
||||||
|
**Dann:** Finding `missing_inverse`
|
||||||
|
**Fix:** Add inverse edge to target note (review + diff)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## C. Semantik: Kausalität vs Chronologie
|
||||||
|
|
||||||
|
### L7 (WARN) Chronology used as Causality
|
||||||
|
**Wenn:** Knoten/Target wirkt wie Prozessschritt („warten“, „gehen“, „ankommen“) und Edge type ist `resulted_in`
|
||||||
|
**Dann:** Finding `chronology_as_causality`
|
||||||
|
**Fix:** Vorschlag `followed_by` (inverse `preceeded_by`)
|
||||||
|
|
||||||
|
### L8 (INFO) Kausalität ohne Brücken (Gap)
|
||||||
|
**Wenn:** Pfad springt von Ereignis direkt zu Entscheidung, aber intermediäre Knoten fehlen (heuristisch)
|
||||||
|
**Dann:** Finding `missing_bridge_node`
|
||||||
|
**Fix:** Vorschlag „Create open_question bridge“ (z.B. „Was war der konkrete Auslöser…?“)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## D. Node-Type Regeln
|
||||||
|
|
||||||
|
### L9 (ERROR) Causal edges from open_question/hypothesis/white_spot
|
||||||
|
**Wenn:** node.type in `{open_question, hypothesis, white_spot}` und Edge type in `{caused_by, resulted_in, impacts, derived_from}`
|
||||||
|
**Dann:** Finding `invalid_causal_edge_from_uncertain`
|
||||||
|
**Fix:** Replace with `related_to` oder remove edge
|
||||||
|
|
||||||
|
### L10 (WARN) Hub/Insight Note trägt Kausalität
|
||||||
|
**Wenn:** node.type == `insight` (oder Hub-Pattern) und hat `caused_by/resulted_in`
|
||||||
|
**Dann:** Finding `hub_has_causality`
|
||||||
|
**Fix:** Replace edges with `related_to` und verschiebe Kausalität in atomare Notes
|
||||||
|
|
||||||
|
### L11 (WARN) Principle uses caused_by for origin
|
||||||
|
**Wenn:** node.type == `principle` und enthält `caused_by` zu Erlebnissen
|
||||||
|
**Dann:** Finding `principle_origin_edge`
|
||||||
|
**Fix:** Vorschlag `derived_from` oder `based_on`
|
||||||
|
|
||||||
|
### L12 (INFO) Decision without caused_by
|
||||||
|
**Wenn:** node.type == `decision` und hat keine `caused_by`-Kanten
|
||||||
|
**Dann:** Finding `decision_without_causes`
|
||||||
|
**Fix:** Wizard: „Was war der Auslöser?“ → create open_question or add edges
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## E. Redundanz & Zyklen
|
||||||
|
|
||||||
|
### L13 (WARN) Duplicate Edges
|
||||||
|
**Wenn:** identische canonical edge mehrfach gesetzt (src,type,dst)
|
||||||
|
**Dann:** Finding `duplicate_edge`
|
||||||
|
**Fix:** remove duplicates
|
||||||
|
|
||||||
|
### L14 (WARN) Cycles in pure causality subgraph
|
||||||
|
**Wenn:** Zyklus ausschließlich über `{caused_by,resulted_in,derived_from,source_of}`
|
||||||
|
**Dann:** Finding `causal_cycle`
|
||||||
|
**Fix:** Markiere zur Review; oft ist eine Kante falsch gerichtet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## F. Traversal-Optimierung (Retrieval-Wirkung)
|
||||||
|
|
||||||
|
### L15 (INFO) Overuse of related_to
|
||||||
|
**Wenn:** Note enthält nur `related_to` und keine spezifischeren Kanten
|
||||||
|
**Dann:** Finding `weak_semantics`
|
||||||
|
**Fix:** Vorschlag: präzisere Beziehungstypen setzen
|
||||||
|
|
||||||
|
### L16 (INFO) Missing type metadata
|
||||||
|
**Wenn:** Frontmatter `type` fehlt
|
||||||
|
**Dann:** Finding `missing_type`
|
||||||
|
**Fix:** Prompt user to choose type; set via template
|
||||||
|
|
||||||
|
### L17 (INFO) Missing date on experience
|
||||||
|
**Wenn:** node.type == `experience` und kein Datum/Zeitraum vorhanden
|
||||||
|
**Dann:** Finding `missing_date_experience`
|
||||||
|
**Fix:** Prompt: „Wann ungefähr?“ → set `date` oder `time_range`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Suggested Implementation Notes
|
||||||
|
- Jede Regel liefert:
|
||||||
|
- `ruleId`, `severity`, `message`, `location`, `evidence`, `quickFixes[]`
|
||||||
|
- QuickFixes sind Patch-Operationen:
|
||||||
|
- replaceText(range, text)
|
||||||
|
- insertBlock(atLine, block)
|
||||||
|
- createFile(path, content)
|
||||||
|
- renameFile(old, new) + updateLinks(glob)
|
||||||
Loading…
Reference in New Issue
Block a user