diff --git a/docs/00_Dokumentations_Index.md b/docs/00_Dokumentations_Index.md new file mode 100644 index 0000000..8e7c055 --- /dev/null +++ b/docs/00_Dokumentations_Index.md @@ -0,0 +1,176 @@ +# Mindnet Causal Assistant - Dokumentations-Index + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Vollständige Übersicht:** Alle Dokumentations-Dateien und deren Inhalte + +--- + +## Dokumentations-Struktur + +### Hauptdokumentation (nach Zielgruppe) + +1. **[01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md)** - Endnutzer +2. **[02_Administratorhandbuch.md](./02_Administratorhandbuch.md)** - Administratoren +3. **[03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md)** - Entwickler +4. **[04_Architektur.md](./04_Architektur.md)** - Architekten +5. **[05_Installation_Deployment.md](./05_Installation_Deployment.md)** - Installation + +### Spezialisierte Referenzen + +6. **[06_Konfigurationsdateien_Referenz.md](./06_Konfigurationsdateien_Referenz.md)** - Config-Dateien Format & Aufbau +7. **[07_Event_Handler_Commands.md](./07_Event_Handler_Commands.md)** - Event Handler & Commands + +### Chain Inspector Reports + +- [CHAIN_INSPECTOR_V0_REPORT.md](./CHAIN_INSPECTOR_V0_REPORT.md) - v0.0 Implementierung +- [CHAIN_INSPECTOR_V02_REPORT.md](./CHAIN_INSPECTOR_V02_REPORT.md) - v0.2 Features +- [CHAIN_INSPECTOR_V03_REPORT.md](./CHAIN_INSPECTOR_V03_REPORT.md) - v0.3 Features +- [CHAIN_INSPECTOR_V04_REPORT.md](./CHAIN_INSPECTOR_V04_REPORT.md) - v0.4 Template Matching +- [CHAIN_INSPECTOR_V042_REPORT.md](./CHAIN_INSPECTOR_V042_REPORT.md) - v0.4.2 Updates + +### Konzepte & Details + +- [02_causal_chain_retrieving.md](./02_causal_chain_retrieving.md) - Kausale Ketten-Retrieval +- [DANGLING_TARGET_CASES.md](./DANGLING_TARGET_CASES.md) - Dangling Target Findings + +### Legacy-Dokumentation + +- [readme.md](./readme.md) - MVP 1.0 Quickstart +- [Handbuch.md](./Handbuch.md) - MVP 1.0 Handbuch +- [TESTING_WITH_REAL_VAULT.md](./TESTING_WITH_REAL_VAULT.md) - Testing mit echtem Vault + +--- + +## Vollständigkeits-Checkliste + +### ✅ Module & Komponenten + +- [x] **Analysis** (`src/analysis/`) - Chain Inspector, Template Matching, Graph Index, Section Context, Severity Policy +- [x] **Commands** (`src/commands/`) - Inspect Chains, Fix Findings +- [x] **Dictionary** (`src/dictionary/`) - Chain Roles Loader, Chain Templates Loader, Config Path Manager, Dictionary Loader, Parsers, Types +- [x] **Entity Picker** (`src/entityPicker/`) - Note Index, Folder Tree, Filters, Wikilink +- [x] **Export** (`src/export/`) - Graph Export +- [x] **Graph** (`src/graph/`) - Graph Builder, Graph Index, Render Chain Report, Resolve Target, Traverse +- [x] **Interview** (`src/interview/`) - Config Loader, Parser, Wizard State, Loop State, Renderer, Write Frontmatter, Section Key Resolver, Extract Target, Slugify +- [x] **Lint** (`src/lint/`) - Lint Engine, Rules (Hub Has Causality, Missing Target, Unknown Edge) +- [x] **Mapping** (`src/mapping/`) - Semantic Mapping Builder, Mapping Extractor, Mapping Builder, Edge Type Selector, Update Mapping Blocks, Section Parser, Worklist Builder, Graph Schema, Schema Helper, Folder Helpers +- [x] **Parser** (`src/parser/`) - Parse Edges From Callouts, Parse Frontmatter, Parse Rel Links +- [x] **Schema** (`src/schema/`) - Graph Schema Loader +- [x] **UI** (`src/ui/`) - Alle Modals (Interview Wizard, Profile Selection, Edge Type Chooser, Entity Picker, Adopt Note, Folder Tree, Link Prompt, Inline Edge Type, Confirm Overwrite), Settings Tab, Markdown Toolbar, Mindnet View +- [x] **Unresolved Link** (`src/unresolvedLink/`) - Handler, Link Helpers, Adopt Helpers +- [x] **Vocabulary** (`src/vocab/`) - Vocabulary, Vocabulary Loader, Parse Edge Vocabulary + +### ✅ Funktionen & Features + +- [x] **Note-Erstellung** - Mit Profilen, Frontmatter-Generierung +- [x] **Interview-Wizard** - Steps, Loops, Nested Loops, Section-basierte Ausgabe +- [x] **Semantic Mapping** - Builder, Extractor, Edge Type Assignment +- [x] **Chain Inspector** - Template Matching, Findings Generation +- [x] **Fix Findings** - Automatische Behebung von Findings +- [x] **Unresolved Link Handling** - Reading View, Editor, Note Adoption +- [x] **Edge-Type-Änderung** - Kontext-Erkennung, Edge Type Selector +- [x] **Graph Export** - JSON-Export +- [x] **Linting** - Lint Engine mit Regeln +- [x] **Live-Reload** - Automatisches Neuladen von Config-Dateien + +### ✅ Commands + +- [x] `mindnet-reload-edge-vocabulary` - Edge Vocabulary neu laden +- [x] `mindnet-validate-current-note` - Note validieren (Lint) +- [x] `mindnet-export-graph` - Graph exportieren +- [x] `mindnet-show-chains-from-current-note` - Ketten von aktueller Note zeigen +- [x] `mindnet-create-note-from-profile` - Note mit Profil erstellen +- [x] `mindnet-change-edge-type` - Edge-Type ändern +- [x] `mindnet-debug-chain-roles` - Chain Roles Debug-Info +- [x] `mindnet-debug-chain-templates` - Chain Templates Debug-Info +- [x] `mindnet-fix-findings` - Findings beheben +- [x] `mindnet-inspect-chains` - Chains analysieren +- [x] `mindnet-build-semantic-mappings` - Semantic Mapping Blöcke bauen + +### ✅ Event Handler + +- [x] **Vault Modify Event** - Live-Reload von Config-Dateien +- [x] **Vault Create Event** - Note Adoption +- [x] **Markdown Post Processor** - Unresolved Link Handling (Reading View) +- [x] **DOM Click Event** - Unresolved Link Handling (Editor) + +### ✅ Settings + +- [x] **Pfad-Settings** (6) - Alle Config-Datei-Pfade +- [x] **Graph & Chain Settings** (4) - maxHops, strictMode, showCanonicalHints, chainDirection +- [x] **Interview Settings** (1) - autoStartInterviewOnCreate +- [x] **Unresolved Link Settings** (6) - interceptUnresolvedLinkClicks, autoStartOnUnresolvedClick, bypassModifier, editorFollowModifier, waitForFirstModifyAfterCreate, waitForModifyTimeoutMs, debugLogging +- [x] **Note Adoption Settings** (4) - adoptNewNotesInEditor, adoptMaxChars, adoptConfirmMode, highConfidenceWindowMs +- [x] **Semantic Mapping Settings** (6) - mappingWrapperCalloutType, mappingWrapperTitle, mappingWrapperFolded, defaultEdgeType, unassignedHandling, allowOverwriteExistingMappings, defaultNotesFolder +- [x] **Inline Micro Edge Suggester Settings** (3) - inlineMicroEnabled, inlineMaxAlternatives, inlineCancelBehavior +- [x] **Export Settings** (1) - exportPath +- [x] **Chain Inspector Settings** (3) - chainInspectorIncludeCandidates, chainInspectorMaxTemplateMatches, templateMatchingProfile +- [x] **Fix Actions Settings** (5) - createMissingNote (mode, defaultTypeStrategy, includeZones), createMissingHeading (level), promoteCandidate (keepOriginal) + +### ✅ Konfigurationsdateien + +- [x] **edge_vocabulary.md** - Format, Parsing-Regeln, Beispiel +- [x] **graph_schema.md** - Format, Parsing-Regeln, Beispiel +- [x] **interview_config.yaml** - Format, Felder, Beispiel (Profile, Steps, Loops) +- [x] **chain_roles.yaml** - Format, Felder, Beispiel (Roles, Edge Types) +- [x] **chain_templates.yaml** - Format, Felder, Beispiel (Templates, Slots, Links, Defaults, Profiles) +- [x] **analysis_policies.yaml** - Geplante Struktur (noch nicht vollständig implementiert) + +### ✅ Wirkungsweise + +- [x] **Live-Reload** - Debounced (200ms), Last-Known-Good Fallback +- [x] **Config-Loading** - YAML/Markdown Parsing, Error Handling +- [x] **Template Matching** - Slot-basiertes Matching, Link Constraints +- [x] **Findings Generation** - Gap-Heuristiken, Severity-Policy +- [x] **Note Adoption** - Confidence-Evaluation, Adoption-Flow +- [x] **Unresolved Link Handling** - Reading View vs Editor, Modifier-Keys +- [x] **Semantic Mapping** - Section-Parsing, Link-Extraktion, Edge-Type-Assignment + +--- + +## Dokumentations-Abdeckung + +### Vollständig dokumentiert + +✅ **Alle Module** - Alle 14 Hauptmodule sind dokumentiert +✅ **Alle Commands** - Alle 11 Commands sind dokumentiert +✅ **Alle Event Handler** - Alle 4 Event Handler sind dokumentiert +✅ **Alle Settings** - Alle 40+ Settings sind dokumentiert +✅ **Alle Config-Dateien** - Alle 6 Config-Dateien sind dokumentiert +✅ **Wirkungsweise** - Alle Hauptfunktionen sind beschrieben +✅ **Konfiguration** - Format und Aufbau aller Config-Dateien sind dokumentiert + +### Teilweise dokumentiert + +⚠️ **Analysis Policies** - Erwähnt, aber noch nicht vollständig implementiert +⚠️ **Einige UI-Komponenten** - Basis-Funktionalität dokumentiert, Details könnten erweitert werden + +### Nicht dokumentiert (nicht vorhanden oder nicht relevant) + +- **Tests** - Test-Dateien sind nicht Teil der Benutzer-Dokumentation +- **Mocks** - Mock-Dateien sind nicht Teil der Benutzer-Dokumentation +- **Build-Scripts** - Build-Scripts sind in Entwicklerhandbuch dokumentiert + +--- + +## Schnellzugriff nach Thema + +### Installation & Setup +→ [05_Installation_Deployment.md](./05_Installation_Deployment.md) + +### Konfiguration +→ [02_Administratorhandbuch.md](./02_Administratorhandbuch.md) +→ [06_Konfigurationsdateien_Referenz.md](./06_Konfigurationsdateien_Referenz.md) + +### Nutzung +→ [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md) +→ [07_Event_Handler_Commands.md](./07_Event_Handler_Commands.md) + +### Entwicklung +→ [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md) +→ [04_Architektur.md](./04_Architektur.md) + +--- + +**Ende des Dokumentations-Index** diff --git a/docs/01_Benutzerhandbuch.md b/docs/01_Benutzerhandbuch.md new file mode 100644 index 0000000..8aa4cc0 --- /dev/null +++ b/docs/01_Benutzerhandbuch.md @@ -0,0 +1,412 @@ +# Mindnet Causal Assistant - Benutzerhandbuch + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Endnutzer des Mindnet Obsidian Plugins + +--- + +## Inhaltsverzeichnis + +1. [Einführung](#einführung) +2. [Schnellstart](#schnellstart) +3. [Hauptfunktionen](#hauptfunktionen) +4. [Workflows](#workflows) +5. [Commands im Detail](#commands-im-detail) +6. [Troubleshooting](#troubleshooting) + +--- + +## Einführung + +Das **Mindnet Causal Assistant** Plugin ist ein Authoring-Tool für Obsidian, das Sie dabei unterstützt: + +- **Strukturierte Notes** anzulegen mit Frontmatter, IDs und Typen +- **Inhalte über konfigurierbare Interviews** zu erfassen +- **Semantische Kanten (Edges)** zu pflegen und zu validieren +- **Links und Edge-Zuordnungen** section-basiert zu gruppieren (Semantic Mapping) +- **Kausale Ketten** zu analysieren und zu validieren + +### Hauptkonzepte + +- **Profile**: Auswahl eines "Erstell-Profils" (kann mehrere Interviews pro Note-Typ geben) +- **Interview Config (YAML)**: Definiert Steps, Loops, Defaults, Frontmatter-Whitelist +- **ID-first**: Mindnet-Graph arbeitet über Frontmatter `id` als Schlüssel +- **Semantic Mapping**: Links in einer Section werden Edge-Typen zugeordnet und als Callouts strukturiert +- **Chain Templates**: Vordefinierte Muster für kausale Ketten (z.B. `trigger → transformation → outcome`) + +--- + +## Schnellstart + +### 1. Plugin aktivieren + +1. Öffnen Sie **Settings → Community Plugins** +2. Stellen Sie sicher, dass "Restricted mode" ausgeschaltet ist +3. Aktivieren Sie das Plugin "Mindnet Causal Assistant" + +### 2. Erste Konfiguration + +Das Plugin benötigt Konfigurationsdateien im Vault. Diese sollten bereits vorhanden sein (siehe Administratorhandbuch). Standardpfade: + +- `_system/dictionary/edge_vocabulary.md` - Edge-Typen-Vokabular +- `_system/dictionary/graph_schema.md` - Graph-Schema +- `_system/dictionary/interview_config.yaml` - Interview-Konfiguration +- `_system/dictionary/chain_roles.yaml` - Chain-Rollen-Mapping +- `_system/dictionary/chain_templates.yaml` - Chain-Templates + +### 3. Erste Note erstellen + +1. Öffnen Sie den Command Palette (`Ctrl+P` / `Cmd+P`) +2. Wählen Sie **"Mindnet: Create note from profile"** +3. Wählen Sie ein Profil aus +4. Geben Sie einen Titel ein +5. Wählen Sie einen Ordner (optional) +6. Die Note wird erstellt und geöffnet +7. Optional: Wizard startet automatisch (wenn konfiguriert) + +--- + +## Hauptfunktionen + +### 1. Note-Erstellung mit Profilen + +**Zweck:** Erstellen strukturierter Mindnet-Notes mit korrektem Frontmatter. + +**Verwendung:** +- Command: **"Mindnet: Create note from profile"** +- Profil wählen (z.B. "experience", "insight", "decision") +- Titel und Ordner festlegen +- Note wird mit Frontmatter erstellt (ID, Typ, Profil) + +**Frontmatter-Beispiel:** +```yaml +--- +id: note_1234567890_abc123 +title: "Meine Erfahrung" +type: experience +interview_profile: experience_basic +--- +``` + +### 2. Interview-Wizard + +**Zweck:** Strukturierte Erfassung von Inhalten über konfigurierbare Interviews. + +**Verwendung:** +- Startet automatisch nach Note-Erstellung (wenn aktiviert) +- Oder manuell über Command (geplant) +- Steps ausfüllen (Loops/Nested Loops möglich) +- Review → Apply & Finish +- Output wird in die Note geschrieben + +**Features:** +- Verschachtelte Loops +- Section-basierte Ausgabe +- Frontmatter-Whitelist-Unterstützung + +### 3. Semantic Mapping (Edger) + +**Zweck:** Automatische Gruppierung von Links nach Edge-Typen in Mapping-Blöcken. + +**Verwendung:** +- **Manuell:** Command **"Mindnet: Build semantic mapping blocks (by section)"** +- **Automatisch:** Nach Interview Finish (falls im Profil aktiviert) + +**Output:** +- Pro Section ein Mapping-Block am Ende der Section: + - Wrapper Callout (Default: `abstract`) + - Gruppiert nach Edge-Typ + - Gruppen getrennt durch Leerzeile + +**Beispiel:** +```markdown +## Meine Section + +Inhalt mit Links: [[Note1]] und [[Note2]] + +> [!abstract] 🕸️ Semantic Mapping +> +> > [!edge] causes +> > [[Note1]] +> > +> > [!edge] influences +> > [[Note2]] +``` + +### 4. Chain Inspector + +**Zweck:** Analyse kausaler Ketten um die aktuelle Section. + +**Verwendung:** +- Command: **"Mindnet: Inspect Chains (Current Section)"** +- Analysiert lokale Nachbarschaft + Pfade im Graphen +- Template Matching gegen vordefinierte Kettenmuster +- Findings (Gap-Heuristiken) werden generiert + +**Report enthält:** +- Context (aktuelle Datei/Section) +- Neighbors (incoming/outgoing) +- Paths (vorwärts/rückwärts) +- Template Matches +- Findings (fehlende Slots, Links, etc.) + +**Findings-Beispiele:** +- `missing_slot_*` - Wichtige Slots fehlen +- `dangling_target` - Edge verweist auf nicht-existierende Datei +- `dangling_target_heading` - Edge verweist auf nicht-existierendes Heading +- `missing_link_constraints` - Erwartete Links fehlen +- `no_causal_roles` - Keine kausalen Rollen gefunden + +### 5. Fix Findings + +**Zweck:** Automatische Behebung von Findings. + +**Verwendung:** +- Command: **"Mindnet: Fix Findings (Current Section)"** +- Zeigt verfügbare Fix-Actions für Findings +- Wählt Action aus → wird ausgeführt + +**Verfügbare Actions:** +- **Create Missing Note** - Erstellt fehlende Note (skeleton oder mit Wizard) +- **Retarget Link** - Ersetzt Link zu existierender Note +- **Create Missing Heading** - Erstellt Heading in Target-Datei +- **Retarget to Existing Heading** - Ersetzt Link zu existierendem Heading +- **Promote Candidate Edge** - Befördert Candidate-Edge zu explizitem Edge + +### 6. Unresolved Link Handling + +**Zweck:** Automatische Note-Erstellung beim Klick auf nicht-existierende Links. + +**Verwendung:** +- Klick auf `[[Neue Note]]` in Reading View oder Editor +- Plugin übernimmt Flow (wenn aktiviert) +- Profil-Auswahl → Note wird erstellt +- Optional: Wizard startet automatisch + +**Modifier-Keys:** +- **Reading View:** Bypass-Modifier (Standard: `Alt`) - umgeht Plugin-Intercept +- **Editor:** Follow-Modifier (Standard: `Ctrl`) - aktiviert Plugin-Intercept + +### 7. Edge-Type-Änderung + +**Zweck:** Ändern des Edge-Typs für Links. + +**Verwendung:** +- Command: **"Mindnet: Edge-Type ändern"** +- Kontext wird automatisch erkannt: + - Cursor in Link → ändert diesen Link + - Auswahl mit Links → ändert alle Links in Auswahl + - Keine Auswahl → zeigt Edge-Type-Selector für neue Links + +**Features:** +- Graph-Schema-basierte Empfehlungen +- Inline Micro-Suggester (wenn aktiviert) +- Typische/Prohibited Edge-Types + +### 8. Note Adoption + +**Zweck:** Automatische Konvertierung neu erstellter Notes zu Mindnet-Format. + +**Verwendung:** +- Automatisch aktiviert (wenn konfiguriert) +- Erkennt neu erstellte Notes (klein, ohne ID) +- Zeigt Adoption-Modal (abhängig von Confidence) +- Profil-Auswahl → Frontmatter wird hinzugefügt +- Optional: Wizard startet + +**Confidence-Levels:** +- **High:** Innerhalb Zeitfenster nach Link-Klick +- **Low:** Andere Fälle + +--- + +## Workflows + +### Workflow 1: Neue Note erstellen und ausfüllen + +1. **Note erstellen:** + - Command: "Mindnet: Create note from profile" + - Profil wählen (z.B. "experience") + - Titel: "Meine Erfahrung" + - Ordner wählen + +2. **Wizard ausfüllen:** + - Wizard startet automatisch (wenn aktiviert) + - Steps durchgehen + - Review → Apply & Finish + +3. **Semantic Mapping:** + - Edger läuft automatisch (falls im Profil aktiviert) + - Oder manuell: "Mindnet: Build semantic mapping blocks" + +4. **Validierung:** + - Command: "Mindnet: Validate current note" + - Prüft Lint-Regeln + - Zeigt Findings in Console + +### Workflow 2: Kausale Kette analysieren + +1. **Section öffnen:** + - Cursor in relevante Section positionieren + +2. **Chain Inspector ausführen:** + - Command: "Mindnet: Inspect Chains (Current Section)" + - Report wird in Console ausgegeben + +3. **Findings prüfen:** + - Console öffnen (F12) + - Findings analysieren + - Template Matches prüfen + +4. **Findings beheben:** + - Command: "Mindnet: Fix Findings (Current Section)" + - Verfügbare Actions auswählen + - Automatische Behebung + +### Workflow 3: Unresolved Link → Note erstellen + +1. **Link erstellen:** + - `[[Neue Note]]` in Note schreiben + +2. **Link anklicken:** + - Reading View: Normaler Klick + - Editor: `Ctrl` + Klick (wenn Follow-Modifier aktiviert) + +3. **Profil wählen:** + - Profile-Selection-Modal öffnet sich + - Profil auswählen + +4. **Note wird erstellt:** + - Frontmatter wird hinzugefügt + - Wizard startet (wenn aktiviert) + +### Workflow 4: Edge-Type ändern + +1. **Link markieren:** + - Cursor in Link positionieren + - Oder mehrere Links auswählen + +2. **Command ausführen:** + - "Mindnet: Edge-Type ändern" + +3. **Edge-Type wählen:** + - Modal zeigt verfügbare Types + - Empfehlungen basierend auf Graph-Schema + - Type auswählen + +4. **Änderung wird angewendet:** + - Link wird aktualisiert + - Semantic Mapping wird aktualisiert (falls vorhanden) + +--- + +## Commands im Detail + +### Note-Erstellung & Interview + +| Command | Beschreibung | Wann verwenden | +|---------|--------------|----------------| +| **Mindnet: Create note from profile** | Erstellt neue Note mit Profil | Neue Note von Grund auf erstellen | +| *(Geplant)* **Mindnet: Start interview wizard** | Startet Wizard für aktuelle Note | Interview manuell starten | + +### Mapping & Edges + +| Command | Beschreibung | Wann verwenden | +|---------|--------------|----------------| +| **Mindnet: Build semantic mapping blocks (by section)** | Baut Semantic Mapping Blöcke | Links nach Edge-Typen gruppieren | +| **Mindnet: Edge-Type ändern** | Ändert Edge-Type für Links | Edge-Typ korrigieren/zuordnen | +| **Mindnet: Reload edge vocabulary** | Lädt Edge-Vokabular neu | Nach Änderung an edge_vocabulary.md | + +### Analyse & Validierung + +| Command | Beschreibung | Wann verwenden | +|---------|--------------|----------------| +| **Mindnet: Inspect Chains (Current Section)** | Analysiert kausale Ketten | Chain-Analyse durchführen | +| **Mindnet: Fix Findings (Current Section)** | Behebt Findings automatisch | Findings automatisch beheben | +| **Mindnet: Validate current note** | Validiert aktuelle Note (Lint) | Note auf Fehler prüfen | + +### Export & Debug + +| Command | Beschreibung | Wann verwenden | +|---------|--------------|----------------| +| **Mindnet: Export graph** | Exportiert Graph als JSON | Graph exportieren | +| **Mindnet: Show chains from current note** | Zeigt Ketten von aktueller Note | Ketten-Exploration | +| **Mindnet: Debug Chain Roles (Loaded)** | Debug-Info für Chain Roles | Debugging | +| **Mindnet: Debug Chain Templates (Loaded)** | Debug-Info für Chain Templates | Debugging | + +> **Detaillierte Referenz:** Siehe [07_Event_Handler_Commands.md](./07_Event_Handler_Commands.md) für vollständige Beschreibung aller Commands, Event Handler und Settings. + +--- + +## Troubleshooting + +### Wizard startet nicht + +**Symptom:** Wizard startet nicht nach Note-Erstellung. + +**Lösung:** +1. Prüfen Sie Settings: `autoStartInterviewOnCreate` +2. Prüfen Sie DevTools Console (F12) auf Fehler +3. Prüfen Sie Interview-Config-Pfad in Settings + +### Edger schreibt Blöcke an falscher Stelle + +**Symptom:** Semantic Mapping Blöcke erscheinen an falscher Position. + +**Lösung:** +1. Prüfen Sie Heading-Parsing (Section-Erkennung) +2. Prüfen Sie, ob Wrapper-Block korrekt erkannt/ersetzt wird +3. Prüfen Sie Console-Logs für Details + +### Schema-Empfehlungen fehlen + +**Symptom:** Keine Empfehlungen beim Edge-Type-Ändern. + +**Lösung:** +1. Prüfen Sie `graph_schema_path` in Settings +2. Prüfen Sie Schema-Loader Stats/Logging in Console +3. Prüfen Sie, ob Schema-Datei existiert und gültig ist + +### Chain Inspector findet keine Matches + +**Symptom:** Template Matches sind leer. + +**Lösung:** +1. Prüfen Sie Chain-Templates-Pfad in Settings +2. Prüfen Sie Console-Logs für Template-Loading +3. Prüfen Sie, ob Note-Types korrekt im Frontmatter sind +4. Prüfen Sie, ob Edges korrekt gemappt sind (chain_roles.yaml) + +### Unresolved Link wird nicht abgefangen + +**Symptom:** Klick auf `[[Neue Note]]` öffnet Obsidian-Dialog statt Plugin-Flow. + +**Lösung:** +1. Prüfen Sie Settings: `interceptUnresolvedLinkClicks` +2. **Reading View:** Bypass-Modifier nicht drücken +3. **Editor:** Follow-Modifier (`Ctrl`) drücken beim Klick +4. Prüfen Sie Console-Logs für Details + +### Note Adoption funktioniert nicht + +**Symptom:** Neu erstellte Notes werden nicht adoptiert. + +**Lösung:** +1. Prüfen Sie Settings: `adoptNewNotesInEditor` +2. Prüfen Sie, ob Note klein genug ist (`adoptMaxChars`) +3. Prüfen Sie, ob Note bereits Frontmatter-ID hat (wird nicht adoptiert) +4. Prüfen Sie Console-Logs für Adoption-Confidence + +--- + +## Weitere Ressourcen + +- **Administratorhandbuch:** Konfiguration und Wartung +- **Entwicklerhandbuch:** Code-Struktur und Erweiterungen +- **Architektur-Dokumentation:** System-Übersicht +- **Installation & Deployment:** Setup-Anleitung + +--- + +**Ende des Benutzerhandbuchs** diff --git a/docs/02_Administratorhandbuch.md b/docs/02_Administratorhandbuch.md new file mode 100644 index 0000000..2314936 --- /dev/null +++ b/docs/02_Administratorhandbuch.md @@ -0,0 +1,514 @@ +# Mindnet Causal Assistant - Administratorhandbuch + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Administratoren, Config-Manager, Vault-Verwalter + +--- + +## Inhaltsverzeichnis + +1. [Überblick](#überblick) +2. [Plugin-Konfiguration](#plugin-konfiguration) +3. [Konfigurationsdateien](#konfigurationsdateien) +4. [Pfad-Management](#pfad-management) +5. [Live-Reload](#live-reload) +6. [Wartung & Troubleshooting](#wartung--troubleshooting) + +--- + +## Überblick + +Das Mindnet Causal Assistant Plugin benötigt mehrere Konfigurationsdateien, die im Vault gespeichert werden. Diese Dateien definieren: + +- **Edge-Vokabular:** Kanonische Edge-Typen und Aliases +- **Graph-Schema:** Empfehlungen für Edge-Typen basierend auf Note-Typen +- **Interview-Config:** Profile, Steps, Loops für Note-Erstellung +- **Chain Roles:** Mapping von Edge-Typen zu kausalen Rollen +- **Chain Templates:** Vordefinierte Kettenmuster für Template Matching + +--- + +## Plugin-Konfiguration + +### Settings-Zugriff + +**Settings → Community Plugins → Mindnet Causal Assistant** + +### Wichtige Settings + +#### Pfad-Settings + +| Setting | Standard | Beschreibung | +|---------|----------|--------------| +| `edgeVocabularyPath` | `_system/dictionary/edge_vocabulary.md` | Pfad zum Edge-Vokabular | +| `graphSchemaPath` | `_system/dictionary/graph_schema.md` | Pfad zum Graph-Schema | +| `interviewConfigPath` | `_system/dictionary/interview_config.yaml` | Pfad zur Interview-Config | +| `chainRolesPath` | `_system/dictionary/chain_roles.yaml` | Pfad zu Chain Roles | +| `chainTemplatesPath` | `_system/dictionary/chain_templates.yaml` | Pfad zu Chain Templates | +| `analysisPoliciesPath` | `_system/dictionary/analysis_policies.yaml` | Pfad zu Analysis Policies | + +#### Feature-Settings + +| Setting | Standard | Beschreibung | +|---------|----------|--------------| +| `interceptUnresolvedLinkClicks` | `true` | Unresolved Links abfangen | +| `autoStartInterviewOnCreate` | `false` | Wizard automatisch starten | +| `adoptNewNotesInEditor` | `true` | Neue Notes automatisch adoptieren | +| `chainInspectorIncludeCandidates` | `false` | Candidate-Edges in Chain Inspector einbeziehen | +| `templateMatchingProfile` | `"discovery"` | Template-Matching-Profil (`discovery` / `decisioning`) | + +#### Fix-Actions-Settings + +| Setting | Standard | Beschreibung | +|---------|----------|--------------| +| `fixActions.createMissingNote.mode` | `"skeleton_only"` | Modus für fehlende Notes | +| `fixActions.createMissingHeading.level` | `2` | Heading-Level für neue Headings | +| `fixActions.promoteCandidate.keepOriginal` | `true` | Original bei Candidate-Promotion behalten | + +--- + +## Konfigurationsdateien + +> **Detaillierte Referenz:** Siehe [06_Konfigurationsdateien_Referenz.md](./06_Konfigurationsdateien_Referenz.md) für vollständige Format-Beschreibungen. + +### 1. Edge Vocabulary (`edge_vocabulary.md`) + +**Zweck:** Definiert kanonische Edge-Typen und Aliases. + +**Format:** Markdown mit Callout-Struktur + +**Beispiel:** +```markdown +# Edge Vocabulary + +> [!edge-type] causes +> Canonical: causes +> Aliases: ausgelöst_durch, verursacht + +> [!edge-type] influences +> Canonical: influences +> Aliases: beeinflusst, wirkt_auf +``` + +**Struktur:** +- `[!edge-type]` Callout mit kanonischem Namen +- `Canonical:` Zeile mit kanonischem Typ +- `Aliases:` Zeile mit komma-separierten Aliases + +**Wartung:** +- Neue Edge-Types hinzufügen: Neuen Callout-Block hinzufügen +- Aliases hinzufügen: Komma-separiert zur `Aliases:` Zeile +- Live-Reload: Automatisch nach Dateiänderung (debounced) + +--- + +### 2. Graph Schema (`graph_schema.md`) + +**Zweck:** Empfehlungen für Edge-Typen basierend auf Source-Note-Typen. + +**Format:** Markdown mit Callout-Struktur + +**Beispiel:** +```markdown +# Graph Schema + +> [!schema] experience +> Typical: causes, influences +> Prohibited: part_of, instance_of +``` + +**Struktur:** +- `[!schema]` Callout mit Note-Type als Titel +- `Typical:` Komma-separierte typische Edge-Types +- `Prohibited:` Komma-separierte verbotene Edge-Types + +**Verwendung:** +- Edge-Type-Selector zeigt Empfehlungen basierend auf Source-Note-Type +- Warnungen bei prohibited Types + +**Wartung:** +- Neue Note-Types hinzufügen: Neuen Callout-Block hinzufügen +- Empfehlungen anpassen: `Typical:` / `Prohibited:` Zeilen ändern +- Live-Reload: Automatisch nach Dateiänderung (debounced) + +--- + +### 3. Interview Config (`interview_config.yaml`) + +**Zweck:** Definiert Profile, Steps, Loops für Note-Erstellung und Interviews. + +**Format:** YAML + +**Struktur:** +```yaml +version: "1.0" +frontmatter_whitelist: + - tags + - status + +profiles: + - key: experience_basic + note_type: experience + description: "Basic experience profile" + defaults: + folder: "experiences" + steps: + - id: context + prompt: "Beschreibe den Kontext" + input_type: textarea + post_run: + edger: true +``` + +**Wichtige Felder:** + +- **`version`:** Config-Version +- **`frontmatter_whitelist`:** Erlaubte Frontmatter-Keys (zusätzlich zu Standard) +- **`profiles`:** Liste von Profilen + - **`key`:** Eindeutiger Profil-Schlüssel + - **`note_type`:** Note-Type (z.B. `experience`, `insight`, `decision`) + - **`defaults`:** Standardwerte (z.B. `folder`) + - **`steps`:** Interview-Steps + - **`post_run`:** Post-Run-Actions (z.B. `edger: true`) + +**Wartung:** +- Neue Profile hinzufügen: Neuen Eintrag unter `profiles` hinzufügen +- Steps anpassen: `steps` Array modifizieren +- Loops hinzufügen: `loop` Feld in Steps verwenden +- Live-Reload: Automatisch nach Dateiänderung (debounced) + +**Validierung:** +- YAML-Syntax wird beim Laden geprüft +- Fehler werden in Console geloggt +- Last-Known-Good wird verwendet bei Fehlern + +--- + +### 4. Chain Roles (`chain_roles.yaml`) + +**Zweck:** Mapping von Edge-Typen zu kausalen Rollen für Template Matching. + +**Format:** YAML + +**Struktur:** +```yaml +version: "1.0" + +roles: + causal: + edge_types: + - causes + - caused_by + - resulted_in + influences: + edge_types: + - influences + - affects + enables_constraints: + edge_types: + - enables + - constrains +``` + +**Rollen:** +- **`causal`:** Direkte kausale Beziehungen +- **`influences`:** Einfluss-Beziehungen +- **`enables_constraints`:** Ermöglicht/Beschränkt-Beziehungen +- **`provenance`:** Herkunfts-Beziehungen + +**Wartung:** +- Neue Rollen hinzufügen: Neuen Eintrag unter `roles` hinzufügen +- Edge-Types zuordnen: `edge_types` Array erweitern +- Live-Reload: Automatisch nach Dateiänderung (debounced) + +**Validierung:** +- YAML-Syntax wird beim Laden geprüft +- Fehler werden in Console geloggt +- Last-Known-Good wird verwendet bei Fehlern + +--- + +### 5. Chain Templates (`chain_templates.yaml`) + +**Zweck:** Vordefinierte Kettenmuster für Template Matching. + +**Format:** YAML + +**Struktur:** +```yaml +version: "1.0" + +defaults: + matching: + required_links: false + +templates: + - name: trigger_transformation_outcome + description: "Causal chain template" + slots: + - id: trigger + allowed_node_types: ["experience"] + - id: transformation + allowed_node_types: ["insight"] + - id: outcome + allowed_node_types: ["decision"] + links: + - from: trigger + to: transformation + allowed_edge_roles: ["causal"] + - from: transformation + to: outcome + allowed_edge_roles: ["causal"] + matching: + required_links: true +``` + +**Wichtige Felder:** + +- **`defaults.matching.required_links`:** Standard für required_links (strict/soft) +- **`templates`:** Liste von Templates + - **`name`:** Template-Name + - **`slots`:** Slot-Definitionen mit `allowed_node_types` + - **`links`:** Link-Constraints mit `allowed_edge_roles` + - **`matching`:** Matching-Parameter (überschreibt Defaults) + +**Wartung:** +- Neue Templates hinzufügen: Neuen Eintrag unter `templates` hinzufügen +- Slots anpassen: `slots` Array modifizieren +- Link-Constraints anpassen: `links` Array modifizieren +- Live-Reload: Automatisch nach Dateiänderung (debounced) + +**Validierung:** +- YAML-Syntax wird beim Laden geprüft +- Fehler werden in Console geloggt +- Last-Known-Good wird verwendet bei Fehlern + +--- + +### 6. Analysis Policies (`analysis_policies.yaml`) + +**Zweck:** Policies für Findings (Severity, Unterdrückung, etc.). + +**Format:** YAML (geplant) + +**Status:** Noch nicht vollständig implementiert + +**Geplante Struktur:** +```yaml +version: "1.0" + +findings: + missing_slot_*: + default_severity: warn + profiles: + discovery: + severity: info + decisioning: + severity: warn + dangling_target: + default_severity: error + suppress_if: [] +``` + +--- + +## Pfad-Management + +### Standard-Pfade + +Alle Konfigurationsdateien werden standardmäßig unter `_system/dictionary/` erwartet: + +``` +_system/ + dictionary/ + edge_vocabulary.md + graph_schema.md + interview_config.yaml + chain_roles.yaml + chain_templates.yaml + analysis_policies.yaml +``` + +### Pfad-Änderung + +**Vorgehen:** +1. Settings öffnen: **Settings → Community Plugins → Mindnet Causal Assistant** +2. Pfad-Setting ändern (z.B. `edgeVocabularyPath`) +3. Settings speichern +4. Plugin lädt Config automatisch neu + +**Hinweise:** +- Pfade sind vault-relativ (beginnen mit `/` oder ohne) +- Forward-Slashes werden normalisiert +- Dateien müssen existieren (sonst Fehler beim Laden) + +--- + +## Live-Reload + +### Automatisches Reload + +**Funktionsweise:** +- Plugin überwacht Konfigurationsdateien auf Änderungen +- Bei Änderung: Debounced Reload (200ms Delay) +- Last-Known-Good wird verwendet bei Fehlern + +**Überwachte Dateien:** +- `edge_vocabulary.md` +- `graph_schema.md` +- `interview_config.yaml` +- `chain_roles.yaml` +- `chain_templates.yaml` + +### Manuelles Reload + +**Commands:** +- **"Mindnet: Reload edge vocabulary"** - Lädt Edge-Vokabular neu + +**Verwendung:** +- Nach größeren Änderungen +- Wenn automatisches Reload nicht funktioniert +- Für Debugging + +### Reload-Status prüfen + +**Console-Logs:** +- Öffnen Sie DevTools (F12) +- Prüfen Sie Console-Logs nach Reload-Events +- Fehler werden geloggt + +**Beispiel-Logs:** +``` +Vocabulary loaded { canonicalCount: 10, aliasCount: 5 } +Interview config reloaded: 3 profile(s) +Chain roles reloaded: 4 roles +Chain templates reloaded: 2 templates +``` + +--- + +## Wartung & Troubleshooting + +### Konfigurationsdateien prüfen + +**YAML-Syntax prüfen:** +```bash +# Mit yamllint (falls installiert) +yamllint _system/dictionary/interview_config.yaml +``` + +**Markdown-Syntax prüfen:** +- Manuelle Prüfung der Callout-Struktur +- Prüfen auf korrekte Formatierung + +### Häufige Probleme + +#### 1. Config wird nicht geladen + +**Symptom:** Plugin zeigt Fehler "Config not found". + +**Lösung:** +1. Prüfen Sie Pfad in Settings +2. Prüfen Sie, ob Datei existiert +3. Prüfen Sie Datei-Berechtigungen +4. Prüfen Sie Console-Logs für Details + +#### 2. YAML-Syntax-Fehler + +**Symptom:** Config wird mit Fehlern geladen. + +**Lösung:** +1. Prüfen Sie YAML-Syntax (z.B. mit yamllint) +2. Prüfen Sie Console-Logs für Fehlerdetails +3. Last-Known-Good wird verwendet (prüfen Sie Logs) +4. Korrigieren Sie Syntax-Fehler + +#### 3. Live-Reload funktioniert nicht + +**Symptom:** Änderungen werden nicht übernommen. + +**Lösung:** +1. Prüfen Sie, ob Datei-Pfad korrekt ist +2. Warten Sie auf Debounce (200ms) +3. Manuelles Reload über Command +4. Plugin neu laden (disable/enable) + +#### 4. Last-Known-Good wird verwendet + +**Symptom:** Console zeigt "using-last-known-good". + +**Lösung:** +1. Prüfen Sie YAML-Syntax-Fehler +2. Korrigieren Sie Fehler +3. Reload wird automatisch versucht +4. Oder manuelles Reload über Command + +### Best Practices + +#### 1. Versionierung + +**Empfehlung:** +- Verwenden Sie Versionsnummern in Config-Dateien +- Dokumentieren Sie Änderungen +- Testen Sie Änderungen in Test-Vault + +#### 2. Backup + +**Empfehlung:** +- Regelmäßige Backups der Config-Dateien +- Git-Versionierung empfohlen +- Vor größeren Änderungen Backup erstellen + +#### 3. Testing + +**Empfehlung:** +- Testen Sie Änderungen in Test-Vault +- Prüfen Sie Console-Logs nach Änderungen +- Validieren Sie YAML-Syntax vor Commit + +#### 4. Dokumentation + +**Empfehlung:** +- Dokumentieren Sie Custom-Profile +- Dokumentieren Sie Custom-Templates +- Kommentare in YAML-Dateien verwenden + +--- + +## Debug-Commands + +### Chain Roles Debug + +**Command:** "Mindnet: Debug Chain Roles (Loaded)" + +**Output:** Console-Log mit: +- Resolved Path +- Status (loaded/error/using-last-known-good) +- Loaded At (Timestamp) +- Errors/Warnings +- Roles-Übersicht + +### Chain Templates Debug + +**Command:** "Mindnet: Debug Chain Templates (Loaded)" + +**Output:** Console-Log mit: +- Resolved Path +- Status (loaded/error/using-last-known-good) +- Loaded At (Timestamp) +- Errors/Warnings +- Templates-Übersicht + +--- + +## Weitere Ressourcen + +- **Benutzerhandbuch:** Endnutzer-Workflows +- **Entwicklerhandbuch:** Code-Struktur und Erweiterungen +- **Architektur-Dokumentation:** System-Übersicht +- **Installation & Deployment:** Setup-Anleitung + +--- + +**Ende des Administratorhandbuchs** diff --git a/docs/02_causal_chain_retrieving.md b/docs/02_causal_chain_retrieving.md new file mode 100644 index 0000000..7c3ea1e --- /dev/null +++ b/docs/02_causal_chain_retrieving.md @@ -0,0 +1,394 @@ +# Mindnet Causal Assistant – Dokumentation der bisher erreichten Resultate (0.4.x) + Architektur, Konfiguration & Strategien + +> Stand: basierend auf den beobachteten Chain-Inspector-Logs und den zuletzt beschriebenen Implementierungen in 0.4.6/0.4.x. +> Ziel dieser Doku: Eine **einheitliche, belastbare Basis**, damit Weiterentwicklung (0.5.x/0.6.x) nicht mehr “im Kreis” läuft. + +--- + +## 1) Zweck & Gesamtziel von Mindnet + +Mindnet soll in einem Obsidian Vault **kausale/argumentative Zusammenhänge** als Graph abbilden und daraus **nützliche Diagnosen** ableiten: + +- **Graph-Aufbau:** Notes/Sections als Knoten, Links/Kanten als gerichtete Beziehungen (z.B. *wirkt_auf*, *resulted_in*, *depends_on* …). +- **Analyse aus einem Kontext:** Nutzer steht in einer Note an einer bestimmten Überschrift/Section → Mindnet analysiert lokale Nachbarschaft + Pfade im Graphen. +- **Template Matching:** Einordnen der gefundenen Knoten/Kanten in “Kettenmuster” (Chain Templates) wie z.B. *trigger → transformation → outcome* oder *loop_learning*. +- **Findings (Gap-Heuristiken):** Hinweise wie “fehlende Slots”, “fehlende Links”, “unmapped edge types”, “einseitige Konnektivität”, etc. + → Ziel: **Nutzer konkret zum besseren Graphen führen**, ohne “Noisy” zu sein. + +--- + +## 2) Begriffe & Datenmodell (so arbeitet der Chain Inspector) + +### 2.1 Kontext (Context) +Der Chain Inspector läuft immer gegen einen **aktuellen Kontext**: +- `file`: aktuelle Note (z.B. `Tests/03_insight_transformation.md`) +- `heading`: aktuelle Section (z.B. `Kern`) +- `zoneKind`: i.d.R. `content` + +Das ist wichtig, weil Kanten teils **section-spezifisch** sind und teils (geplant/teilweise offen) **note-weit** gelten könnten. + +--- + +### 2.2 Knoten (Nodes) +Ein Knoten ist im Report meist referenziert als: +- `file + heading` (z.B. `Tests/01_experience_trigger.md:Kontext`) +- plus abgeleitete Metadaten wie `noteType` (z.B. experience, insight, decision, event) + +**noteType** ist entscheidend fürs Template Matching (Slots). + +--- + +### 2.3 Kanten (Edges) +Eine Kante hat typischerweise: +- `rawEdgeType`: Original-Typ aus Markdown/Notation (z.B. `wirkt_auf`, `resulted_in`, `depends_on`, `derived_from`, …) +- `from`: Quelle (file:heading) +- `to`: Ziel (file:heading) +- `scope`: Gültigkeit / Herkunft + - `section`: Edge ist “voll gültig” für die Section + - `candidate`: Edge ist nur Kandidat/unsicher, wird optional zugelassen + - (geplant/offen) `note`: Edge gilt note-weit (unabhängig von Section) +- `evidence`: Fundstelle (file, sectionHeading, lineRange) + +--- + +## 3) Erreichte Resultate in 0.4.x (verifiziert) + +### 3.1 includeCandidates – Kandidatenkanten funktionieren wie erwartet +**Ergebnis (bereits mehrfach in Logs verifiziert):** +- Wenn `includeCandidates=false`, werden Kanten mit `scope: candidate` **im effektiven Graphen ausgefiltert**. +- Wenn `includeCandidates=true`, werden Kandidatenkanten **als incoming/outgoing** berücksichtigt und tauchen in `neighbors`/`paths` auf. + +**Implikation:** +- Das System kann “unsichere” oder “LLM-vorschlagene” Verbindungen existieren lassen, ohne in jedem Lauf die Analyse zu verfälschen. +- In “Discovery” kann man Kandidaten zulassen (mehr Explorationspower). +- In “Decisioning” kann man Kandidaten typischerweise sperren (mehr Verlässlichkeit). + +--- + +### 3.2 required_links: Strict vs Soft Mode – missing_link_constraints Unterdrückung ist umgesetzt +**Problem (historisch):** +- `missing_link_constraints` wurde teilweise auch dann ausgegeben, wenn `required_links=false` (Soft Mode) aktiv war → unnötig “noisy”. + +**Fix (laut Cursor-Report umgesetzt + Tests):** +- `missing_link_constraints` wird nur erzeugt, wenn `effectiveRequiredLinks === true`. +- Es gibt eine definierte Auflösungsreihenfolge für `required_links`: + +**Resolution Order (effective required_links):** +1. `template.matching?.required_links` +2. `profile.required_links` +3. `defaults.matching?.required_links` +4. Fallback: `false` + +**Transparenz bleibt erhalten:** +- `satisfiedLinks` und `requiredLinks` werden weiterhin im Report angezeigt. +- `linksComplete` bleibt als technischer Wert im Report bestehen. +- **Nur** das Finding `missing_link_constraints` wird unterdrückt, nicht die Fakten. + +**Implikation:** +- Soft Mode (= required_links=false) ist jetzt ruhig genug, um “Entdeckung” zu unterstützen. +- Strict Mode (= required_links=true) eignet sich für harte Qualitätskontrolle. + +--- + +### 3.3 “Healthy graph” → Findings leer ([]), Template “confirmed” +Wenn Slots **und** geforderte Links erfüllt sind (z.B. `trigger_transformation_outcome` mit 2/2 Links), +dann ist `findings: []` das erwartete Ergebnis. + +**Implikation:** +- Das ist das zentrale “Green Path”-Signal: Graph ist konsistent für das gewählte Template/Profil. + +--- + +### 3.4 Unmapped edges werden erkannt (Diagnose) +Wenn ein `rawEdgeType` nicht in die kanonischen Rollen/Edge-Rollen abgebildet werden kann, tauchen typischerweise Diagnosen auf: +- `edgesUnmapped > 0` +- Findings wie `no_causal_roles` oder link constraints bleiben unerfüllt + +**Implikation:** +- Das Rollen-Mapping (chain_roles.yaml) ist “critical path”: wenn ein Edge-Typ nicht gemappt wird, bricht oft der kausale Interpretationspfad. + +--- + +## 4) Was ist (noch) offen – echtes nächstes Verifikationsziel + +### 4.1 Note-Level Edges / Note-Scope (“für jede Sektion gültig”) +Es existiert ein Konzept/Einbau: In `02_event_trigger_detail` gibt es einen Bereich, der Kanten **auf Note-Ebene** definieren soll (unabhängig von aktueller Section). + +**Offen ist die robuste Verifikation (oder Implementierung), dass:** +- diese Edges auch dann gelten, wenn der Cursor in einer anderen Section derselben Note steht, +- idealerweise mit klar erkennbarer Kennzeichnung wie `scope: note` im Report. + +**Warum ist das wichtig?** +- Das ermöglicht “globaler Kontext” pro Note, ohne alles in jede Section duplizieren zu müssen. +- Es ist eine UX-Optimierung: Nutzer kann “Meta-Verbindungen” an einer Stelle pflegen. + +--- + +## 5) Konfigurationsdateien – Rolle & Interpretation (Mindnet-Strategie) + +> Die folgenden Bereiche beschreiben eine **saubere, konsistente Interpretation**, wie Mindnet die Configs verwenden sollte. +> Konkrete Keys, die in Logs sichtbar waren (z.B. required_links, min_slots_filled_for_gap_findings, min_score_for_gap_findings) sind hier berücksichtigt. + +### 5.1 chain_templates.yaml – “Welche Ketten gibt es, wie werden sie gematcht?” +**Zweck:** +- Definiert Templates (Muster), z.B.: + - `trigger_transformation_outcome` + - `loop_learning` + - ggf. weitere (constraint_to_adaptation usw.) + +**Template enthält typischerweise:** +- Slots (Rollen für Knoten): z.B. `trigger`, `transformation`, `outcome`, `experience`, `learning`, `behavior`, `feedback` +- Required Link Constraints (welche Slot-zu-Slot Verbindungen zwingend sind) +- Scoring/Matching-Parameter (ggf. weights, thresholds) +- Optional: template-level override für `required_links` + +**Matching-Profile (wie in Logs sichtbar):** +- z.B. Profile: `discovery`, `decisioning` +- Parameter im Profil (sichtbar in Logs): + - `required_links` (strict vs soft) + - `min_slots_filled_for_gap_findings` + - `min_score_for_gap_findings` + - ggf. `maxTemplateMatches` + +**Interpretation:** +- Templates liefern die “Soll-Struktur” +- Profile bestimmen “Wie streng” wir die Soll-Struktur im jeweiligen Workflow bewerten + +--- + +### 5.2 chain_roles.yaml – “Welche rawEdgeTypes zählen als welche Rollen?” +**Zweck:** +- Mappt `rawEdgeType` → kanonische Rollen/EdgeRoles (z.B. `causal`, `influences`, `enables_constraints`, `provenance`). +- Diese Rollen sind Grundlage für: + - `no_causal_roles` Finding + - Link-Constraint-Satisfaction (Template erwartet “causal” zwischen Slots) + - Matching Score (welche Edges zählen für welches Template) + +**Interpretation:** +- Wenn ein Edge-Typ nicht gemappt ist: + - Edge kann trotzdem im Graph auftauchen, + - aber Template/Constraint-Logik kann ihn nicht “verstehen” → führt zu Findings. + +--- + +### 5.3 analysis_policies.yaml – “Wie noisy dürfen Findings sein?” +**Zweck:** +- Zentrale Policies für Findings: + - welche Finding-Codes existieren + - Default-Severity (info/warn/error) + - Profilabhängige Overrides + - Unterdrückungsregeln (z.B. suppress in soft mode, suppress wenn confirmed, suppress wenn Score hoch…) + +**Interpretation:** +- Policies sind “produktseitige UX-Regeln”: + - Discovery: eher informativ, weniger warn + - Decisioning: klare Warnungen, wenn Qualität fehlt +- Der bereits umgesetzte Fix (`missing_link_constraints` nur in strict) ist exakt so eine Policy-Entscheidung (auch wenn technisch im Inspector gelöst). + +--- + +## 6) Ablauf des Chain Inspectors (Vorgehensweise in Mindnet) + +Hier ist ein konsistenter “Pipeline”-Ablauf, der zu den Logs passt: + +### Schritt 1: Kontext bestimmen +- Aktuelle Datei + aktuelle Section/Heading + +### Schritt 2: Edges aus aktueller Note laden +- Outgoing aus der aktuellen Section extrahieren (oder aus einem definierten Block) +- (optional/offen) Note-Level Edges ebenfalls laden und für jede Section gültig machen + +### Schritt 3: Nachbarn laden +- Backlinks (Notes, die auf die aktuelle Note verlinken) → incoming Kandidatenquellen +- Outgoing Neighbor Notes (Notes, auf die aktuelle Note verweist) → Nachbarschaft erweitern + +### Schritt 4: Edges aus Neighbor Notes laden +- Aus den verlinkenden Notes die Edges extrahieren, die auf die aktuelle Note/Section zielen +- Canonicalization: rawEdgeTypes via chain_roles.yaml in Rollen überführen + +### Schritt 5: Kandidatenfilter / Scopefilter anwenden +- Wenn `includeCandidates=false`: + - `scope: candidate` aus effective graph entfernen +- Optional weitere Filter: + - includeNoteLinks / includeSectionLinks + - direction (forward/backward/both) + - maxDepth (Traversal) + +### Schritt 6: Pfade berechnen (Paths) +- Forward/Backward (oder both) +- BFS/DFS bis `maxDepth` +- Resultat: Pfadlisten mit nodes + edges + +### Schritt 7: Template Matching +- Kandidatenknoten für Slots finden (via noteType + Nähe + Pfade) +- Links/Constraints prüfen (erwartete slot→slot Beziehungen) +- Score berechnen (z.B. per: + - Slots erfüllt + - Link constraints erfüllt + - “RoleEvidence” passend) + +### Schritt 8: Findings berechnen (Gap-Heuristics) +Beispiele: +- `missing_slot_*` wenn wichtige Slots fehlen (abhängig von Profil-Thresholds) +- `one_sided_connectivity` wenn nur incoming oder nur outgoing +- `no_causal_roles` wenn Edges da, aber keine causal Rollen im effektiven Graph +- `missing_link_constraints` nur wenn effectiveRequiredLinks=true und slotsComplete=true, requiredLinks>0, linksComplete=false + +### Schritt 9: Report ausgeben +- context, settings, neighbors, paths, findings, analysisMeta, templateMatches +- Transparenz: satisfiedLinks/requiredLinks/linksComplete bleiben sichtbar + +--- + +## 7) Strategien, die Mindnet verfolgen kann (Produkt-/UX-Strategie) + +### Strategie A: Discovery (Exploration) +**Ziel:** Möglichst schnell “wo könnte eine sinnvolle Kette entstehen?” finden. +- required_links = false (Soft Mode) +- includeCandidates = true (optional) +- findings eher informativ (info), weniger warn +- Templates mehr als Vorschläge (“plausible/weak”), nicht als harte Bewertung + +**Vorteil:** Nutzer bekommt schnell Hypothesen. +**Risiko:** Mehr Noise, mehr falsche Kandidaten – muss per Policy gedämpft werden. + +--- + +### Strategie B: Decisioning (Qualitätskontrolle) +**Ziel:** Prüfung, ob eine Kette “wirklich steht” und als belastbar gelten kann. +- required_links = true (Strict Mode) +- includeCandidates = false +- findings: warn, wenn Slots/Links fehlen +- “confirmed” nur wenn link constraints komplett + +**Vorteil:** Qualitätssicherung & Verlässlichkeit. +**Risiko:** Nutzer fühlt sich “blockiert”, wenn Graph noch im Aufbau ist. + +--- + +### Strategie C: Progressive Disclosure (hybrid) +**Ziel:** Nutzer nicht überfordern, aber zielgerichtet verbessern. +- Soft Mode für Einstieg +- Button/Toggle: “Strict prüfen” +- Candidate Edges als Vorschlag-Klasse (UI: “proposed edges”) +- Findings priorisieren: erst fehlende Slots, dann fehlende Links, dann Detail-Qualität + +--- + +## 8) Wie ein “kausaler Retriever” funktionieren könnte (Causal Retriever) + +Ein kausaler Retriever ist die Komponente, die aus dem Vault/Graphen **relevante Kausalkontexte** für den aktuellen Abschnitt liefert – idealerweise deterministisch, skalierbar und template-aware. + +### 8.1 Retrieval-Ziele +- Finde Knoten/Edges, die **kausal relevant** sind zum aktuellen Kontext: + - Ursachen (backward) + - Wirkungen/Entscheidungen (forward) + - Bedingungen/Constraints (seitlich) +- Gib nicht nur Knoten zurück, sondern: + - Pfade (explainable) + - Evidence (wo steht das) + - Role-Interpretation (warum ist das causal/influences/etc.) + +### 8.2 Retrieval-Inputs +- startNode = current section +- direction = forward/backward/both +- maxDepth +- roleFilter (optional): nur causal/influences/enables_constraints +- scopeFilter: includeCandidates, includeNoteLevel +- templateBias: bevorzugte Pfadformen (z.B. “experience→insight→decision”) + +### 8.3 Retrieval-Algorithmus (praktisch) +**Variante 1: BFS mit Rolle-Gewichtung** +- BFS über Kanten +- Priorität/Score pro Frontier: + - causal > influences > provenance + - section-scope > note-scope > candidate (wenn candidates eingeschaltet, sonst candidate=∞) +- Stop, wenn: + - maxDepth erreicht + - genug Top-N Pfade gesammelt (z.B. topNUsed) + +**Variante 2: Template-driven Retrieval** +- Wenn ein Template im Fokus ist: + - suche explizit nach Slot-Knoten (noteType matching) + - suche dann die minimalen Verbindungen, die Constraints erfüllen +- Gute Option für “Decisioning”: deterministisch prüfen. + +**Variante 3: Two-phase Retrieval** +1) Kandidaten finden (Slots) +2) Verbindungen prüfen (Constraints) +→ Liefert sehr gut “warum fehlt Link X?” Diagnosen. + +### 8.4 Output-Format +- `neighbors` (incoming/outgoing, mit evidence) +- `paths` (forward/backward, nodes+edges) +- plus “slot candidates” optional (für UI) + +--- + +## 9) Empfehlungen für robuste Tests (damit ihr nicht wieder im Kreis lauft) + +### Was ist bereits ausreichend getestet (nicht wiederholen) +- includeCandidates Filterverhalten ✅ +- missing_link_constraints Unterdrückung bei required_links=false ✅ +- strict/soft required_links via profile/template override ✅ +- “healthy graph” ergibt findings: [] ✅ +- unmapped edge type triggert Diagnose ✅ + +### Was als einziges “neues” Testziel für Abschluss 0.4.x/Start 0.5.x taugt +- **Note-level edges / note-scope**: gelten Kanten “global” pro Note oder nicht? + +**Minimal-Testdefinition (einmalig, reproduzierbar):** +1) In `02_event_trigger_detail.md` einen klaren Note-Level Block definieren (z.B. “## Note-Verbindungen”). +2) Edge dort definieren, die auf eine andere Note/Section zeigt. +3) Cursor in einer anderen Section derselben Note platzieren (z.B. “## Detail” oder “## Extra”). +4) Chain Inspector laufen lassen. +5) Erwartung: + - Edge erscheint trotzdem als outgoing/incoming + - evidence zeigt auf den Note-Level Block + - ideal: `scope: note` + +Wenn das FAIL ist → klarer 0.5.0 Task. + +--- + +## 10) Implikationen für 0.5.x / 0.6.x (wohin sinnvoll weiter) + +### 0.5.x (Stabilisierung) +- Note-level edge scope finalisieren (inkl. Report-Transparenz) +- policies (analysis_policies) als zentrale Noise-Steuerung weiter ausbauen +- Debug/Explainability weiter verbessern (effectiveRequiredLinks pro Match explizit ausgeben) + +### 0.6.x (UX & Workflows) +- Actionable Findings: “Was genau soll ich ändern?” inkl. Vorschlagtext oder Snippet +- UI-Toggles: Strict/Soft, Candidates on/off +- Template Authoring Tools: Linter, “Warum kein Match?” + +--- + +## 11) Kurzes “Was heißt das für Mindnet im Alltag?” +- Im Discovery-Modus: Mindnet ist ein **Explorationswerkzeug** (Hypothesen + Hinweise, wenig Warnungen). +- Im Decisioning-Modus: Mindnet ist ein **Qualitätsprüfer** (strict, wenige false positives). +- Der nächste große Hebel ist Note-scope: Damit wird Pflege einfacher und Ketten werden “wartbarer”. + +--- + +## 12) Appendix: Beispielhafte Report-Signale (Interpretationshilfe) + +- `findings: []` + `confidence: confirmed` + → Template passt sauber (Slots + Links vollständig im gewählten Modus). + +- `linksComplete=false` aber `required_links=false` und **kein** `missing_link_constraints` + → Soft Mode: bewusst kein “Warn-Noise”, aber Transparenz bleibt. + +- `no_causal_roles` + → Edges existieren, aber keine davon wird als “causal” interpretiert (Mapping oder rawEdgeType Problem). + +- `edgesUnmapped > 0` + → chain_roles unvollständig oder Edge-Typ ist neu/fehlerhaft geschrieben. + +- `effectiveIncoming=0` bei includeCandidates=false, aber incoming candidate-edge existiert + → Filter funktioniert wie geplant. + +--- + +ENDE diff --git a/docs/03_Entwicklerhandbuch.md b/docs/03_Entwicklerhandbuch.md new file mode 100644 index 0000000..6a532b0 --- /dev/null +++ b/docs/03_Entwicklerhandbuch.md @@ -0,0 +1,914 @@ +# Mindnet Causal Assistant - Entwicklerhandbuch + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Entwickler, die am Plugin arbeiten oder es erweitern + +--- + +## Inhaltsverzeichnis + +1. [Überblick](#überblick) +2. [Projekt-Struktur](#projekt-struktur) +3. [Entwicklungsumgebung](#entwicklungsumgebung) +4. [Code-Architektur](#code-architektur) +5. [Hauptmodule](#hauptmodule) +6. [Erweiterungen entwickeln](#erweiterungen-entwickeln) +7. [Testing](#testing) +8. [Build & Deployment](#build--deployment) + +--- + +## Überblick + +Das Mindnet Causal Assistant Plugin ist ein **Obsidian Community Plugin** geschrieben in **TypeScript**, gebündelt mit **esbuild** zu einer einzelnen `main.js` Datei. + +### Technologie-Stack + +- **Sprache:** TypeScript (strict mode) +- **Bundler:** esbuild +- **Package Manager:** npm +- **Testing:** Vitest +- **Linting:** ESLint mit obsidianmd Plugin + +### Projekt-Typ + +- **Obsidian Community Plugin** +- **Entry Point:** `src/main.ts` → `main.js` +- **Release-Artefakte:** `main.js`, `manifest.json`, optional `styles.css` + +--- + +## Projekt-Struktur + +``` +mindnet_obsidian/ +├── src/ # TypeScript Source Code +│ ├── main.ts # Plugin Entry Point +│ ├── settings.ts # Settings Interface & Defaults +│ ├── analysis/ # Chain Inspector & Analysis +│ │ ├── chainInspector.ts # Haupt-Analyse-Engine +│ │ ├── templateMatching.ts # Template Matching Algorithmus +│ │ ├── graphIndex.ts # Graph-Indexierung +│ │ ├── sectionContext.ts # Section-Context-Handling +│ │ └── severityPolicy.ts # Severity-Policy-Logik +│ ├── commands/ # Command Implementations +│ │ ├── inspectChainsCommand.ts +│ │ └── fixFindingsCommand.ts +│ ├── dictionary/ # Config Loader & Parser +│ │ ├── ChainRolesLoader.ts +│ │ ├── ChainTemplatesLoader.ts +│ │ ├── DictionaryLoader.ts +│ │ ├── parseChainRoles.ts +│ │ ├── parseChainTemplates.ts +│ │ └── types.ts +│ ├── entityPicker/ # Entity Selection UI +│ │ ├── noteIndex.ts +│ │ ├── folderTree.ts +│ │ ├── filters.ts +│ │ ├── wikilink.ts +│ │ └── types.ts +│ ├── export/ # Graph Export +│ │ ├── exportGraph.ts +│ │ └── types.ts +│ ├── graph/ # Graph Building & Traversal +│ │ ├── GraphBuilder.ts +│ │ ├── GraphIndex.ts +│ │ ├── renderChainReport.ts +│ │ ├── resolveTarget.ts +│ │ └── traverse.ts +│ ├── interview/ # Interview Wizard +│ │ ├── InterviewConfigLoader.ts +│ │ ├── parseInterviewConfig.ts +│ │ ├── wizardState.ts +│ │ ├── loopState.ts +│ │ └── renderer.ts +│ ├── lint/ # Linting Engine +│ │ ├── LintEngine.ts +│ │ └── rules/ +│ ├── mapping/ # Semantic Mapping +│ │ ├── semanticMappingBuilder.ts +│ │ ├── mappingExtractor.ts +│ │ ├── mappingBuilder.ts +│ │ └── edgeTypeSelector.ts +│ ├── parser/ # Markdown Parsing +│ │ ├── parseEdgesFromCallouts.ts +│ │ ├── parseFrontmatter.ts +│ │ └── parseRelLinks.ts +│ ├── schema/ # Graph Schema +│ ├── ui/ # UI Components +│ │ ├── InterviewWizardModal.ts +│ │ ├── ProfileSelectionModal.ts +│ │ ├── MindnetSettingTab.ts +│ │ └── ... +│ ├── unresolvedLink/ # Unresolved Link Handling +│ ├── vocab/ # Edge Vocabulary +│ └── tests/ # Test Files +├── docs/ # Dokumentation +├── scripts/ # Build Scripts +│ └── deploy-local.ps1 +├── package.json # Dependencies & Scripts +├── tsconfig.json # TypeScript Config +├── esbuild.config.mjs # Build Config +├── manifest.json # Plugin Manifest +└── main.js # Generated Bundle (nicht committen) +``` + +--- + +## Entwicklungsumgebung + +### Voraussetzungen + +- **Node.js:** LTS Version (18+ empfohlen) +- **npm:** Inkludiert mit Node.js +- **Git:** Für Versionierung +- **Obsidian Desktop:** Für Testing + +### Setup + +```bash +# Repository klonen +git clone mindnet_obsidian +cd mindnet_obsidian + +# Dependencies installieren +npm install + +# Development Build (Watch Mode) +npm run dev + +# Production Build +npm run build + +# Tests ausführen +npm run test + +# Linting +npm run lint +``` + +### Development Workflow + +1. **Code ändern** in `src/` +2. **Watch Mode** läuft (`npm run dev`) +3. **Automatisches Rebuild** bei Dateiänderungen +4. **Deploy lokal** (`npm run deploy:local` oder `npm run build:deploy`) +5. **Obsidian Plugin reload** (disable/enable) +6. **Testen** + +--- + +## Code-Architektur + +### Plugin Lifecycle + +**Entry Point:** `src/main.ts` + +```typescript +export default class MindnetCausalAssistantPlugin extends Plugin { + settings: MindnetSettings; + + async onload(): Promise { + await this.loadSettings(); + this.addSettingTab(new MindnetSettingTab(this.app, this)); + // Register commands, event handlers, etc. + } + + onunload(): void { + // Cleanup + } +} +``` + +### Settings Management + +**Datei:** `src/settings.ts` + +```typescript +export interface MindnetSettings { + edgeVocabularyPath: string; + graphSchemaPath: string; + // ... weitere Settings +} + +export const DEFAULT_SETTINGS: MindnetSettings = { + edgeVocabularyPath: "_system/dictionary/edge_vocabulary.md", + // ... Defaults +}; +``` + +**Laden/Speichern:** +```typescript +async loadSettings(): Promise { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); +} + +async saveSettings(): Promise { + await this.saveData(this.settings); +} +``` + +### Command Registration + +**Pattern:** +```typescript +this.addCommand({ + id: "mindnet-command-id", + name: "Mindnet: Command Name", + callback: async () => { + // Implementation + }, +}); +``` + +**Editor Callbacks:** +```typescript +this.addCommand({ + id: "mindnet-editor-command", + name: "Mindnet: Editor Command", + editorCallback: async (editor) => { + // Editor-basierte Implementation + }, +}); +``` + +--- + +## Hauptmodule + +### 1. Analysis (`src/analysis/`) + +**Zweck:** Chain Inspector & Template Matching + +**Hauptdateien:** +- `chainInspector.ts` - Haupt-Analyse-Engine +- `templateMatching.ts` - Template Matching Algorithmus +- `graphIndex.ts` - Graph-Indexierung für Traversal +- `sectionContext.ts` - Section-Context-Extraktion +- `severityPolicy.ts` - Severity-Policy-Logik + +**Verwendung:** +```typescript +import { executeInspectChains } from "./commands/inspectChainsCommand"; + +await executeInspectChains( + app, + editor, + activeFile.path, + chainRoles, + settings, + {}, + chainTemplates, + templatesLoadResult +); +``` + +### 2. Dictionary (`src/dictionary/`) + +**Zweck:** Config Loading & Parsing + +**Hauptdateien:** +- `ChainRolesLoader.ts` - Lädt chain_roles.yaml +- `ChainTemplatesLoader.ts` - Lädt chain_templates.yaml +- `DictionaryLoader.ts` - Basis-Loader mit Error-Handling +- `parseChainRoles.ts` - YAML → ChainRolesConfig Parser +- `parseChainTemplates.ts` - YAML → ChainTemplatesConfig Parser + +**Pattern:** +```typescript +const result = await ChainRolesLoader.load( + app, + settings.chainRolesPath, + lastKnownGood +); + +if (result.data !== null) { + // Use result.data +} +``` + +**Last-Known-Good:** +- Bei Fehlern wird letzte gültige Config verwendet +- `lastKnownGood` Parameter für Fallback + +### 3. Graph (`src/graph/`) + +**Zweck:** Graph Building & Traversal + +**Hauptdateien:** +- `GraphBuilder.ts` - Baut Graph aus Vault +- `GraphIndex.ts` - Indexiert Edges für Traversal +- `traverse.ts` - BFS/DFS Traversal +- `resolveTarget.ts` - Link-Target-Auflösung +- `renderChainReport.ts` - Report-Generierung + +**Verwendung:** +```typescript +const graph = await buildGraph(app, vocabulary); +const index = buildIndex(graph.edges); +const paths = traverseForward(index, startId, maxHops, maxPaths); +``` + +### 4. Interview (`src/interview/`) + +**Zweck:** Interview Wizard für Note-Erstellung + +**Hauptdateien:** +- `InterviewConfigLoader.ts` - Lädt interview_config.yaml +- `parseInterviewConfig.ts` - YAML → InterviewConfig Parser +- `wizardState.ts` - Wizard State Management (Steps, Loops, Nested Loops) +- `loopState.ts` - Loop State Management (nested loops) +- `renderer.ts` - Output-Rendering (Section-basiert) +- `writeFrontmatter.ts` - Frontmatter-Generierung +- `sectionKeyResolver.ts` - Section-Key-Auflösung +- `extractTargetFromAnchor.ts` - Target-Extraktion aus Anchors +- `slugify.ts` - Slug-Generierung für Dateinamen +- `types.ts` - Interview-Types + +**Verwendung:** +```typescript +import { InterviewConfigLoader } from "./interview/InterviewConfigLoader"; +import { writeFrontmatter } from "./interview/writeFrontmatter"; +import { InterviewWizardModal } from "./ui/InterviewWizardModal"; + +// Config laden +const result = await InterviewConfigLoader.loadConfig(app, configPath); +const config = result.config; + +// Frontmatter schreiben +const frontmatter = writeFrontmatter({ + id: "note_123", + title: "Meine Note", + noteType: "experience", + interviewProfile: "experience_basic", + defaults: profile.defaults, + frontmatterWhitelist: config.frontmatterWhitelist, +}); + +// Wizard starten +const modal = new InterviewWizardModal(app, profile, onFinish); +modal.open(); +``` + +**Features:** +- **Nested Loops:** Unterstützung für verschachtelte Loops +- **Section-basierte Ausgabe:** Output wird in Sections geschrieben +- **Frontmatter-Whitelist:** Erlaubte Frontmatter-Keys +- **Post-Run Actions:** Automatische Actions nach Wizard (z.B. Edger) + +### 5. Mapping (`src/mapping/`) + +**Zweck:** Semantic Mapping Builder + +**Hauptdateien:** +- `semanticMappingBuilder.ts` - Haupt-Mapping-Builder +- `mappingExtractor.ts` - Extrahiert existierende Mappings +- `mappingBuilder.ts` - Baut neue Mappings +- `edgeTypeSelector.ts` - Edge-Type-Selection UI + +**Verwendung:** +```typescript +import { buildSemanticMappings } from "./mapping/semanticMappingBuilder"; + +const result = await buildSemanticMappings( + app, + activeFile, + settings, + allowOverwrite, + plugin +); +``` + +### 6. Parser (`src/parser/`) + +**Zweck:** Markdown Parsing + +**Hauptdateien:** +- `parseEdgesFromCallouts.ts` - Extrahiert Edges aus Callouts +- `parseFrontmatter.ts` - Frontmatter-Parsing +- `parseRelLinks.ts` - Relative Link-Parsing + +**Verwendung:** +```typescript +import { parseEdgesFromCallouts } from "./parser/parseEdgesFromCallouts"; + +const edges = parseEdgesFromCallouts(content, file, vocabulary); +``` + +### 7. UI (`src/ui/`) + +**Zweck:** UI Components (Modals, Views) + +**Hauptdateien:** +- `InterviewWizardModal.ts` - Interview Wizard UI +- `ProfileSelectionModal.ts` - Profil-Auswahl UI +- `MindnetSettingTab.ts` - Settings Tab +- `EdgeTypeChooserModal.ts` - Edge-Type-Auswahl UI +- `EntityPickerModal.ts` - Entity-Auswahl UI +- `AdoptNoteModal.ts` - Note-Adoption-Confirmation +- `FolderTreeModal.ts` - Folder-Auswahl UI +- `LinkPromptModal.ts` - Link-Eingabe UI +- `InlineEdgeTypeModal.ts` - Inline Edge-Type-Selection +- `ConfirmOverwriteModal.ts` - Overwrite-Confirmation + +**Pattern:** +```typescript +export class MyModal extends Modal { + constructor(app: App, onResult: (result: MyResult) => void) { + super(app); + this.onResult = onResult; + } + + onOpen() { + // Build UI + } + + onClose() { + // Cleanup + } +} +``` + +### 8. Vocabulary (`src/vocab/`) + +**Zweck:** Edge Vocabulary Management + +**Hauptdateien:** +- `Vocabulary.ts` - Wrapper-Klasse für Lookup-Methoden +- `VocabularyLoader.ts` - Lädt Vocabulary-Datei +- `parseEdgeVocabulary.ts` - Parst Markdown zu EdgeVocabulary +- `types.ts` - Vocabulary-Types + +**Verwendung:** +```typescript +import { VocabularyLoader } from "./vocab/VocabularyLoader"; +import { parseEdgeVocabulary } from "./vocab/parseEdgeVocabulary"; +import { Vocabulary } from "./vocab/Vocabulary"; + +const text = await VocabularyLoader.loadText(app, path); +const parsed = parseEdgeVocabulary(text); +const vocabulary = new Vocabulary(parsed); + +const canonical = vocabulary.getCanonical("ausgelöst_durch"); +const normalized = vocabulary.normalize("causes"); +``` + +### 9. Lint (`src/lint/`) + +**Zweck:** Linting Engine für Note-Validierung + +**Hauptdateien:** +- `LintEngine.ts` - Haupt-Linting-Engine +- `rules/index.ts` - Regel-Registry +- `rules/rule_hub_has_causality.ts` - Kausalitäts-Prüfung +- `rules/rule_missing_target.ts` - Fehlende Target-Prüfung +- `rules/rule_unkown_edge.ts` - Unbekannte Edge-Type-Prüfung +- `types.ts` - Lint-Types + +**Verwendung:** +```typescript +import { LintEngine } from "./lint/LintEngine"; + +const findings = await LintEngine.lintCurrentNote( + app, + vocabulary, + { showCanonicalHints: true } +); +``` + +### 10. Export (`src/export/`) + +**Zweck:** Graph Export zu JSON + +**Hauptdateien:** +- `exportGraph.ts` - Haupt-Export-Funktion +- `types.ts` - Export-Types + +**Verwendung:** +```typescript +import { exportGraph } from "./export/exportGraph"; + +await exportGraph(app, vocabulary, "_system/exports/graph.json"); +``` + +### 11. Schema (`src/schema/`) + +**Zweck:** Graph Schema Loading + +**Hauptdateien:** +- `GraphSchemaLoader.ts` - Lädt Graph-Schema-Datei + +**Verwendung:** +```typescript +import { GraphSchemaLoader } from "./schema/GraphSchemaLoader"; + +const schema = await GraphSchemaLoader.load(app, schemaPath); +const typical = schema.getTypicalEdgeTypes("experience"); +``` + +### 12. Unresolved Link (`src/unresolvedLink/`) + +**Zweck:** Unresolved Link Handling + +**Hauptdateien:** +- `unresolvedLinkHandler.ts` - Haupt-Handler für Link-Clicks +- `linkHelpers.ts` - Link-Parsing und -Normalisierung +- `adoptHelpers.ts` - Note-Adoption-Logik + +**Verwendung:** +```typescript +import { isUnresolvedLink, normalizeLinkTarget } from "./unresolvedLink/linkHelpers"; +import { isAdoptCandidate, evaluateAdoptionConfidence } from "./unresolvedLink/adoptHelpers"; + +const unresolved = isUnresolvedLink(app, linkTarget, sourcePath); +const confidence = evaluateAdoptionConfidence(file, content, maxChars, hint, windowMs); +``` + +### 13. Entity Picker (`src/entityPicker/`) + +**Zweck:** Entity Selection (Notes, Folders) + +**Hauptdateien:** +- `noteIndex.ts` - Baut Index aller Notes +- `folderTree.ts` - Folder-Tree-Struktur +- `filters.ts` - Filter-Logik +- `wikilink.ts` - Wikilink-Parsing +- `types.ts` - Entity-Picker-Types + +**Verwendung:** +```typescript +import { buildNoteIndex } from "./entityPicker/noteIndex"; +import { buildFolderTree } from "./entityPicker/folderTree"; + +const index = await buildNoteIndex(app); +const tree = buildFolderTree(app); +``` + +### 14. Commands (`src/commands/`) + +**Zweck:** Command Implementations + +**Hauptdateien:** +- `inspectChainsCommand.ts` - Chain Inspector Command +- `fixFindingsCommand.ts` - Fix Findings Command + +**Verwendung:** +```typescript +import { executeInspectChains } from "./commands/inspectChainsCommand"; +import { executeFixFindings } from "./commands/fixFindingsCommand"; + +await executeInspectChains(app, editor, filePath, chainRoles, settings, {}, chainTemplates, result); +await executeFixFindings(app, editor, filePath, chainRoles, interviewConfig, settings, plugin); +``` + +--- + +## Erweiterungen entwickeln + +### 1. Neuen Command hinzufügen + +**Schritt 1:** Command in `main.ts` registrieren + +```typescript +this.addCommand({ + id: "mindnet-my-command", + name: "Mindnet: My Command", + callback: async () => { + // Implementation + }, +}); +``` + +**Schritt 2:** Implementation in separater Datei (optional) + +```typescript +// src/commands/myCommand.ts +export async function executeMyCommand( + app: App, + settings: MindnetSettings +): Promise { + // Implementation +} +``` + +**Schritt 3:** In `main.ts` importieren und verwenden + +```typescript +import { executeMyCommand } from "./commands/myCommand"; + +this.addCommand({ + id: "mindnet-my-command", + name: "Mindnet: My Command", + callback: async () => { + await executeMyCommand(this.app, this.settings); + }, +}); +``` + +### 2. Neue Lint-Regel hinzufügen + +**Schritt 1:** Regel-Datei erstellen + +```typescript +// src/lint/rules/rule_my_rule.ts +import type { LintRule, LintFinding } from "../types"; + +export const ruleMyRule: LintRule = { + id: "my_rule", + name: "My Rule", + severity: "WARN", + check: async (app, file, vocabulary): Promise => { + const findings: LintFinding[] = []; + // Check logic + return findings; + }, +}; +``` + +**Schritt 2:** Regel registrieren + +```typescript +// src/lint/rules/index.ts +import { ruleMyRule } from "./rule_my_rule"; + +export const RULES = [ + ruleMyRule, + // ... weitere Regeln +]; +``` + +### 3. Neues Finding hinzufügen + +**Schritt 1:** Finding-Code definieren + +```typescript +// In chainInspector.ts oder templateMatching.ts +const finding: Finding = { + code: "my_finding", + severity: "WARN", + message: "My finding message", + evidence: { /* ... */ }, +}; +``` + +**Schritt 2:** Finding generieren + +```typescript +if (condition) { + findings.push({ + code: "my_finding", + severity: "WARN", + message: "My finding message", + evidence: { /* ... */ }, + }); +} +``` + +### 4. Neues UI-Element hinzufügen + +**Schritt 1:** Modal/Component erstellen + +```typescript +// src/ui/MyModal.ts +import { Modal } from "obsidian"; + +export class MyModal extends Modal { + constructor(app: App, onResult: (result: MyResult) => void) { + super(app); + this.onResult = onResult; + } + + onOpen() { + const { contentEl } = this; + // Build UI + } + + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +} +``` + +**Schritt 2:** Modal verwenden + +```typescript +import { MyModal } from "./ui/MyModal"; + +new MyModal(this.app, (result) => { + // Handle result +}).open(); +``` + +--- + +## Testing + +### Test-Setup + +**Framework:** Vitest + +**Konfiguration:** `vitest.config.ts` + +**Test-Dateien:** `src/tests/**/*.test.ts` + +### Tests ausführen + +```bash +# Alle Tests +npm run test + +# Watch Mode +npm run test -- --watch + +# Spezifische Datei +npm run test -- src/tests/analysis/chainInspector.test.ts +``` + +### Test-Pattern + +```typescript +import { describe, it, expect } from "vitest"; + +describe("MyModule", () => { + it("should do something", () => { + const result = myFunction(input); + expect(result).toBe(expected); + }); +}); +``` + +### Mocking + +**Obsidian API Mocking:** +```typescript +// src/__mocks__/obsidian.ts +export const mockApp = { + vault: { /* ... */ }, + metadataCache: { /* ... */ }, + // ... +}; +``` + +--- + +## Build & Deployment + +### Development Build + +```bash +npm run dev +``` + +**Ergebnis:** +- `main.js` wird erstellt (mit Source Maps) +- Watch Mode aktiviert +- Automatisches Rebuild bei Änderungen + +### Production Build + +```bash +npm run build +``` + +**Ergebnis:** +- `main.js` wird erstellt (minified, ohne Source Maps) +- TypeScript-Check wird ausgeführt +- Tree-Shaking aktiviert + +### Lokales Deployment + +**Windows (PowerShell):** +```bash +npm run deploy:local +# oder +powershell -ExecutionPolicy Bypass -File scripts/deploy-local.ps1 +``` + +**Script:** `scripts/deploy-local.ps1` +- Kopiert `main.js`, `manifest.json` nach Vault Plugin-Ordner +- Optional: `styles.css` falls vorhanden + +**Zielpfad:** +``` +/.obsidian/plugins/mindnet-causal-assistant/ +``` + +### Release-Prozess + +1. **Version bumpen:** + ```bash + npm version patch|minor|major + ``` + - Aktualisiert `manifest.json` und `package.json` + - Fügt Eintrag zu `versions.json` hinzu + +2. **Build:** + ```bash + npm run build + ``` + +3. **Git Commit:** + ```bash + git add manifest.json versions.json + git commit -m "Release v1.0.1" + git tag v1.0.1 + ``` + +4. **GitHub Release:** + - Erstelle Release mit Tag `v1.0.1` (ohne `v` Prefix) + - Upload `main.js`, `manifest.json`, optional `styles.css` + +--- + +## Code-Standards + +### TypeScript + +- **Strict Mode:** Aktiviert +- **No Implicit Any:** Aktiviert +- **Strict Null Checks:** Aktiviert +- **Module Resolution:** Node + +### Code-Organisation + +- **Ein Datei = Ein Verantwortungsbereich** +- **Klare Module-Grenzen** +- **Keine zirkulären Dependencies** +- **Tests neben Source-Code** + +### Naming Conventions + +- **Dateien:** `camelCase.ts` (z.B. `chainInspector.ts`) +- **Klassen:** `PascalCase` (z.B. `ChainInspector`) +- **Funktionen:** `camelCase` (z.B. `executeInspectChains`) +- **Interfaces:** `PascalCase` (z.B. `MindnetSettings`) +- **Types:** `PascalCase` (z.B. `ChainRolesConfig`) + +### Kommentare + +- **JSDoc** für öffentliche APIs +- **Inline-Kommentare** für komplexe Logik +- **TODO-Kommentare** für geplante Features + +--- + +## Debugging + +### Console-Logging + +```typescript +console.log("[Module] Message", data); +console.warn("[Module] Warning", data); +console.error("[Module] Error", data); +``` + +### Debug-Settings + +**Settings:** `debugLogging: boolean` + +**Verwendung:** +```typescript +if (this.settings.debugLogging) { + console.log("[Module] Debug info", data); +} +``` + +### DevTools + +**Öffnen:** `Ctrl+Shift+I` (Windows/Linux) oder `Cmd+Option+I` (Mac) + +**Console:** Für Logs und Errors +**Network:** Für API-Calls (falls vorhanden) +**Sources:** Für Source Maps (Development Build) + +--- + +## Bekannte Einschränkungen + +### Obsidian API + +- **Mobile:** Nicht alle APIs verfügbar +- **Desktop-only:** `isDesktopOnly: true` im Manifest +- **CodeMirror:** Abhängig von Obsidian-Version + +### Performance + +- **Graph Building:** Kann bei großen Vaults langsam sein +- **Live-Reload:** Debounced (200ms) für Performance +- **Template Matching:** BFS-Limit (max 30 Nodes) + +--- + +## Weitere Ressourcen + +- **Benutzerhandbuch:** Endnutzer-Workflows +- **Administratorhandbuch:** Konfiguration und Wartung +- **Architektur-Dokumentation:** System-Übersicht +- **Installation & Deployment:** Setup-Anleitung +- **Obsidian API Docs:** https://docs.obsidian.md + +--- + +**Ende des Entwicklerhandbuchs** diff --git a/docs/04_Architektur.md b/docs/04_Architektur.md new file mode 100644 index 0000000..cf6ddc9 --- /dev/null +++ b/docs/04_Architektur.md @@ -0,0 +1,683 @@ +# Mindnet Causal Assistant - Architektur-Dokumentation + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Architekten, Entwickler, System-Designer + +--- + +## Inhaltsverzeichnis + +1. [System-Überblick](#system-überblick) +2. [Architektur-Prinzipien](#architektur-prinzipien) +3. [Komponenten-Architektur](#komponenten-architektur) +4. [Datenfluss](#datenfluss) +5. [Konfigurations-Management](#konfigurations-management) +6. [Erweiterbarkeit](#erweiterbarkeit) + +--- + +## System-Überblick + +### Zweck + +Das **Mindnet Causal Assistant** Plugin ist ein Authoring-Tool für Obsidian, das kausale/argumentative Zusammenhänge als Graph abbildet und daraus nützliche Diagnosen ableitet. + +### Kern-Funktionen + +1. **Note-Erstellung:** Strukturierte Notes mit Frontmatter, IDs, Typen +2. **Interview-Wizard:** Konfigurierbare Interviews zur Inhaltserfassung +3. **Semantic Mapping:** Section-basierte Gruppierung von Links nach Edge-Typen +4. **Chain Inspector:** Analyse kausaler Ketten mit Template Matching +5. **Findings & Fixes:** Automatische Erkennung und Behebung von Problemen + +### Technologie-Stack + +- **Sprache:** TypeScript (strict mode) +- **Framework:** Obsidian Plugin API +- **Bundler:** esbuild +- **Testing:** Vitest +- **Config-Format:** YAML, Markdown + +--- + +## Architektur-Prinzipien + +### 1. Modularität + +**Prinzip:** Klare Trennung von Verantwortlichkeiten + +- **Analysis:** Chain Inspector, Template Matching +- **Dictionary:** Config Loading & Parsing +- **Graph:** Graph Building & Traversal +- **Interview:** Wizard & State Management +- **Mapping:** Semantic Mapping Builder +- **Parser:** Markdown Parsing + +### 2. Konfigurierbarkeit + +**Prinzip:** Externe Konfiguration über Vault-Dateien + +- **Edge Vocabulary:** Edge-Typen & Aliases +- **Graph Schema:** Empfehlungen für Edge-Types +- **Interview Config:** Profile, Steps, Loops +- **Chain Roles:** Edge-Type → Role Mapping +- **Chain Templates:** Vordefinierte Kettenmuster + +### 3. Live-Reload + +**Prinzip:** Automatisches Neuladen bei Config-Änderungen + +- **Debounced Reload:** 200ms Delay für Performance +- **Last-Known-Good:** Fallback bei Fehlern +- **Error-Handling:** Graceful Degradation + +### 4. Extensibility + +**Prinzip:** Erweiterbar durch neue Module + +- **Lint Rules:** Neue Regeln hinzufügbar +- **Findings:** Neue Finding-Codes definierbar +- **Templates:** Neue Chain-Templates konfigurierbar +- **UI Components:** Modals/Views erweiterbar + +--- + +## Komponenten-Architektur + +### High-Level-Architektur + +``` +┌─────────────────────────────────────────────────────────┐ +│ Obsidian Plugin API │ +└─────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ MindnetCausalAssistantPlugin │ +│ (main.ts) │ +│ - Settings Management │ +│ - Command Registration │ +│ - Event Handlers │ +└─────────────────────────────────────────────────────────┘ + │ + ┌───────────────────┼───────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ Analysis │ │ Dictionary │ │ Graph │ +│ │ │ │ │ │ +│ - Inspector │ │ - Loaders │ │ - Builder │ +│ - Matching │ │ - Parsers │ │ - Traversal │ +│ - Findings │ │ - Types │ │ - Index │ +└──────────────┘ └──────────────┘ └──────────────┘ + │ │ │ + └───────────────────┼───────────────────┘ + │ + ┌───────────────────┼───────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ Interview │ │ Mapping │ │ Parser │ +│ │ │ │ │ │ +│ - Wizard │ │ - Builder │ │ - Edges │ +│ - State │ │ - Extractor │ │ - Frontmatter│ +│ - Renderer │ │ - Selector │ │ - Links │ +└──────────────┘ └──────────────┘ └──────────────┘ + │ │ │ + └───────────────────┼───────────────────┘ + │ + ┌───────────────────┼───────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ Vocabulary │ │ Lint │ │ Export │ +│ │ │ │ │ │ +│ - Loader │ │ - Engine │ │ - Graph │ +│ - Normalize │ │ - Rules │ │ - Serialize │ +│ - Cache │ │ - Findings │ │ - JSON │ +└──────────────┘ └──────────────┘ └──────────────┘ + │ │ │ + └───────────────────┼───────────────────┘ + │ + ┌───────────────────┼───────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ Schema │ │UnresolvedLink│ │EntityPicker │ +│ │ │ │ │ │ +│ - Loader │ │ - Handler │ │ - Index │ +│ - Lookup │ │ - Adoption │ │ - Filters │ +│ - Cache │ │ - Resolution │ │ - Tree │ +└──────────────┘ └──────────────┘ └──────────────┘ +``` + +### Komponenten-Details + +#### 1. Plugin Core (`main.ts`) + +**Verantwortlichkeiten:** +- Plugin Lifecycle (onload/onunload) +- Settings Management +- Command Registration +- Event Handler Registration +- Config Loading Coordination + +**Abhängigkeiten:** +- Obsidian Plugin API +- Alle anderen Module + +#### 2. Analysis (`src/analysis/`) + +**Verantwortlichkeiten:** +- Chain Inspector (Haupt-Analyse-Engine) +- Template Matching (Slot-basiertes Matching) +- Graph Indexierung (für Traversal) +- Section Context Extraction +- Findings Generation + +**Abhängigkeiten:** +- Dictionary (Chain Roles, Templates) +- Graph (Traversal, Index) +- Parser (Edge Extraction) + +**Datenfluss:** +``` +Context → Graph Building → Traversal → Template Matching → Findings +``` + +#### 3. Dictionary (`src/dictionary/`) + +**Verantwortlichkeiten:** +- Config Loading (YAML, Markdown) +- Config Parsing (YAML → TypeScript Types) +- Error Handling (Last-Known-Good) +- Live-Reload Coordination + +**Abhängigkeiten:** +- Obsidian Vault API +- YAML Parser + +**Datenfluss:** +``` +Vault File → Loader → Parser → TypeScript Types → Cache +``` + +#### 4. Graph (`src/graph/`) + +**Verantwortlichkeiten:** +- Graph Building (aus Vault) +- Graph Indexierung (für Traversal) +- Traversal (BFS/DFS) +- Target Resolution (Link → File) +- Report Rendering + +**Abhängigkeiten:** +- Parser (Edge Extraction) +- Obsidian Metadata Cache + +**Datenfluss:** +``` +Vault → Graph Builder → Graph Index → Traversal → Paths +``` + +#### 5. Interview (`src/interview/`) + +**Verantwortlichkeiten:** +- Wizard State Management +- Loop State Management (nested loops) +- Output Rendering (Section-basiert) +- Frontmatter Writing +- Section Key Resolution +- Target Extraction from Anchors + +**Abhängigkeiten:** +- Dictionary (Interview Config) +- UI (Wizard Modal) +- Parser (Frontmatter) + +**Datenfluss:** +``` +Config → Wizard State → User Input → Loop State → Renderer → Note Content +``` + +**Hauptkomponenten:** +- `InterviewConfigLoader.ts` - Lädt interview_config.yaml +- `parseInterviewConfig.ts` - YAML → InterviewConfig Parser +- `wizardState.ts` - Wizard State Management (Steps, Loops) +- `loopState.ts` - Loop State Management (nested loops) +- `renderer.ts` - Output-Rendering (Section-basiert) +- `writeFrontmatter.ts` - Frontmatter-Generierung +- `sectionKeyResolver.ts` - Section-Key-Auflösung +- `extractTargetFromAnchor.ts` - Target-Extraktion aus Anchors +- `slugify.ts` - Slug-Generierung für Dateinamen + +#### 6. Mapping (`src/mapping/`) + +**Verantwortlichkeiten:** +- Semantic Mapping Builder +- Mapping Extraction (aus existierenden Blöcken) +- Edge Type Selection (UI) +- Mapping Block Updates + +**Abhängigkeiten:** +- Parser (Link Extraction) +- Schema (Graph Schema für Empfehlungen) +- UI (Edge Type Selector) + +**Datenfluss:** +``` +Note Content → Link Extraction → Edge Type Assignment → Mapping Blocks +``` + +#### 7. Parser (`src/parser/`) + +**Verantwortlichkeiten:** +- Edge Extraction (aus Callouts) +- Frontmatter Parsing +- Link Parsing (Relative Links) +- Section Detection + +**Abhängigkeiten:** +- Obsidian Metadata Cache +- Vocabulary (Edge Normalization) + +**Datenfluss:** +``` +Markdown → Parser → Structured Data (Edges, Links, Frontmatter) +``` + +#### 8. Vocabulary (`src/vocab/`) + +**Verantwortlichkeiten:** +- Edge Vocabulary Loading (aus Markdown) +- Edge Type Normalization (Alias → Canonical) +- Inverse Edge Type Resolution +- Vocabulary Caching + +**Abhängigkeiten:** +- Obsidian Vault API +- Markdown Parser + +**Datenfluss:** +``` +Vault File → VocabularyLoader → Parser → Vocabulary Instance → Cache +``` + +**Hauptkomponenten:** +- `Vocabulary.ts` - Wrapper-Klasse für Lookup-Methoden +- `VocabularyLoader.ts` - Lädt Vocabulary-Datei +- `parseEdgeVocabulary.ts` - Parst Markdown zu EdgeVocabulary-Struktur + +#### 9. Lint (`src/lint/`) + +**Verantwortlichkeiten:** +- Linting Engine für Note-Validierung +- Regel-basierte Prüfungen +- Findings Generation + +**Abhängigkeiten:** +- Vocabulary (Edge Type Validation) +- Parser (Edge Extraction) +- Obsidian Metadata Cache + +**Datenfluss:** +``` +Note Content → Parser → Lint Rules → Findings +``` + +**Hauptkomponenten:** +- `LintEngine.ts` - Haupt-Linting-Engine +- `rules/` - Einzelne Lint-Regeln + - `rule_hub_has_causality.ts` - Prüft auf kausale Edges + - `rule_missing_target.ts` - Prüft auf fehlende Targets + - `rule_unkown_edge.ts` - Prüft auf unbekannte Edge-Types + +#### 10. Export (`src/export/`) + +**Verantwortlichkeiten:** +- Graph Export zu JSON +- Node/Edge Serialisierung +- Export-Datei-Erstellung + +**Abhängigkeiten:** +- Graph (Graph Building) +- Vocabulary (Edge Normalization) +- Parser (Edge Extraction) + +**Datenfluss:** +``` +Vault → Graph Builder → Export Serialization → JSON File +``` + +**Hauptkomponenten:** +- `exportGraph.ts` - Haupt-Export-Funktion +- `types.ts` - Export-Types (ExportBundle, ExportNode, ExportEdge) + +#### 11. Schema (`src/schema/`) + +**Verantwortlichkeiten:** +- Graph Schema Loading (aus Markdown) +- Schema-basierte Empfehlungen für Edge-Types +- Typical/Prohibited Edge-Type-Lookup + +**Abhängigkeiten:** +- Obsidian Vault API +- Markdown Parser + +**Datenfluss:** +``` +Vault File → GraphSchemaLoader → Schema Instance → Cache +``` + +**Hauptkomponenten:** +- `GraphSchemaLoader.ts` - Lädt Graph-Schema-Datei +- Verwendet von `mapping/graphSchema.ts` für Empfehlungen + +#### 12. Unresolved Link (`src/unresolvedLink/`) + +**Verantwortlichkeiten:** +- Unresolved Link Detection +- Link Click Interception (Reading View, Editor) +- Note Adoption Flow +- Link Target Resolution + +**Abhängigkeiten:** +- Obsidian Metadata Cache +- Interview (Note Creation) +- Entity Picker (Target Selection) + +**Datenfluss:** +``` +Link Click → Detection → Profile Selection → Note Creation → Adoption +``` + +**Hauptkomponenten:** +- `unresolvedLinkHandler.ts` - Haupt-Handler für Link-Clicks +- `linkHelpers.ts` - Link-Parsing und -Normalisierung +- `adoptHelpers.ts` - Note-Adoption-Logik + +#### 13. Entity Picker (`src/entityPicker/`) + +**Verantwortlichkeiten:** +- Entity Selection UI (Notes, Folders) +- Note Index Building +- Folder Tree Navigation +- Wikilink Parsing + +**Abhängigkeiten:** +- Obsidian Vault API +- UI (EntityPickerModal) + +**Datenfluss:** +``` +Vault → Note Index → Filters → Entity Selection → Result +``` + +**Hauptkomponenten:** +- `noteIndex.ts` - Baut Index aller Notes +- `folderTree.ts` - Folder-Tree-Struktur +- `filters.ts` - Filter-Logik für Entity-Selection +- `wikilink.ts` - Wikilink-Parsing + +#### 14. Commands (`src/commands/`) + +**Verantwortlichkeiten:** +- Command Implementations +- Command Execution Coordination +- Error Handling für Commands + +**Abhängigkeiten:** +- Alle anderen Module (je nach Command) + +**Hauptkomponenten:** +- `inspectChainsCommand.ts` - Chain Inspector Command +- `fixFindingsCommand.ts` - Fix Findings Command + +--- + +## Datenfluss + +### Workflow 1: Chain Inspector + +``` +1. User: Command "Inspect Chains" + ↓ +2. main.ts: executeInspectChains() + ↓ +3. sectionContext.ts: Extract Context (file, heading) + ↓ +4. parser/: Extract Edges from Section + ↓ +5. graphIndex.ts: Build Index from Edges + ↓ +6. traverse.ts: BFS/DFS Traversal + ↓ +7. templateMatching.ts: Match Templates + ↓ +8. chainInspector.ts: Generate Findings + ↓ +9. Console: Output Report +``` + +### Workflow 2: Note Creation + +``` +1. User: Command "Create Note from Profile" + ↓ +2. main.ts: Profile Selection Modal + ↓ +3. dictionary/: Load Interview Config + ↓ +4. interview/: Write Frontmatter + ↓ +5. vault.create(): Create File + ↓ +6. interview/: Start Wizard (if enabled) + ↓ +7. wizardState.ts: Collect User Input + ↓ +8. renderer.ts: Render Output + ↓ +9. vault.modify(): Write Content + ↓ +10. mapping/: Run Edger (if enabled) +``` + +### Workflow 3: Semantic Mapping + +``` +1. User: Command "Build Semantic Mapping" + ↓ +2. mappingExtractor.ts: Extract Existing Mappings + ↓ +3. sectionParser.ts: Parse Sections + ↓ +4. parseRelLinks.ts: Extract Links + ↓ +5. edgeTypeSelector.ts: Assign Edge Types + ↓ +6. mappingBuilder.ts: Build Mapping Blocks + ↓ +7. updateMappingBlocks.ts: Update Note + ↓ +8. vault.modify(): Write Content +``` + +### Workflow 4: Config Reload + +``` +1. Vault: File Modified (edge_vocabulary.md) + ↓ +2. main.ts: Vault Modify Event + ↓ +3. Debounce Timer (200ms) + ↓ +4. VocabularyLoader: Load File + ↓ +5. parseEdgeVocabulary: Parse Markdown + ↓ +6. Vocabulary: Create Instance + ↓ +7. Cache: Update Vocabulary + ↓ +8. Notice: "Vocabulary reloaded" +``` + +--- + +## Konfigurations-Management + +### Config-Loading-Pattern + +**Basis-Pattern:** +```typescript +interface DictionaryLoadResult { + status: "loaded" | "error" | "using-last-known-good"; + data: T | null; + errors: string[]; + warnings: string[]; + resolvedPath: string; + loadedAt: number | null; +} +``` + +**Last-Known-Good:** +- Bei Fehlern wird letzte gültige Config verwendet +- `lastKnownGood` Parameter für Fallback +- Graceful Degradation statt Crash + +**Live-Reload:** +- Debounced (200ms) für Performance +- Automatisches Neuladen bei Dateiänderungen +- Error-Handling mit Last-Known-Good + +### Config-Hierarchie + +``` +1. Vault File (YAML/Markdown) + ↓ +2. Loader (File → Text) + ↓ +3. Parser (Text → TypeScript Types) + ↓ +4. Validator (Type Checking) + ↓ +5. Cache (In-Memory) + ↓ +6. Consumer (Plugin Components) +``` + +--- + +## Erweiterbarkeit + +### Erweiterungspunkte + +#### 1. Lint Rules + +**Schnittstelle:** +```typescript +interface LintRule { + id: string; + name: string; + severity: "ERROR" | "WARN" | "INFO"; + check: (app: App, file: TFile, vocabulary: Vocabulary) => Promise; +} +``` + +**Erweiterung:** +- Neue Regel-Datei in `src/lint/rules/` +- Regel in `src/lint/rules/index.ts` registrieren + +#### 2. Findings + +**Schnittstelle:** +```typescript +interface Finding { + code: string; + severity: "ERROR" | "WARN" | "INFO"; + message: string; + evidence: Record; +} +``` + +**Erweiterung:** +- Neuen Finding-Code definieren +- Finding in Chain Inspector generieren +- Optional: Fix Action hinzufügen + +#### 3. Chain Templates + +**Erweiterung:** +- Neues Template in `chain_templates.yaml` hinzufügen +- Slots und Links definieren +- Template Matching unterstützt automatisch + +#### 4. UI Components + +**Schnittstelle:** +```typescript +class MyModal extends Modal { + constructor(app: App, onResult: (result: MyResult) => void); + onOpen(): void; + onClose(): void; +} +``` + +**Erweiterung:** +- Neue Modal-Klasse erstellen +- In Commands verwenden + +--- + +## Performance-Überlegungen + +### Optimierungen + +1. **Debouncing:** Config-Reload (200ms) +2. **Caching:** In-Memory Cache für Configs +3. **Lazy Loading:** Configs werden bei Bedarf geladen +4. **BFS-Limit:** Template Matching (max 30 Nodes) +5. **Tree-Shaking:** Unused Code wird entfernt + +### Bottlenecks + +1. **Graph Building:** Kann bei großen Vaults langsam sein +2. **Template Matching:** Backtracking kann bei vielen Templates langsam sein +3. **Live-Reload:** Zu viele Reloads können Performance beeinträchtigen + +--- + +## Sicherheit & Robustheit + +### Error-Handling + +- **Last-Known-Good:** Fallback bei Config-Fehlern +- **Try-Catch:** Alle async Operations +- **Graceful Degradation:** Plugin funktioniert auch bei Teilfehlern + +### Validierung + +- **YAML-Syntax:** Wird beim Laden geprüft +- **Type-Checking:** TypeScript strict mode +- **Runtime-Validierung:** Config-Struktur wird geprüft + +### Isolation + +- **Module-Grenzen:** Klare Trennung von Verantwortlichkeiten +- **Keine zirkulären Dependencies** +- **Obsidian API:** Isoliert von anderen Plugins + +--- + +## Weitere Ressourcen + +- **Benutzerhandbuch:** Endnutzer-Workflows +- **Administratorhandbuch:** Konfiguration und Wartung +- **Entwicklerhandbuch:** Code-Struktur und Erweiterungen +- **Installation & Deployment:** Setup-Anleitung + +--- + +**Ende der Architektur-Dokumentation** diff --git a/docs/05_Installation_Deployment.md b/docs/05_Installation_Deployment.md new file mode 100644 index 0000000..1c0148c --- /dev/null +++ b/docs/05_Installation_Deployment.md @@ -0,0 +1,492 @@ +# Mindnet Causal Assistant - Installation & Deployment + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Administratoren, Entwickler, Erst-Installation + +--- + +## Inhaltsverzeichnis + +1. [Voraussetzungen](#voraussetzungen) +2. [Installation](#installation) +3. [Deployment](#deployment) +4. [Konfiguration](#konfiguration) +5. [Upgrade](#upgrade) +6. [Troubleshooting](#troubleshooting) + +--- + +## Voraussetzungen + +### System-Anforderungen + +- **Betriebssystem:** Windows, macOS, Linux +- **Obsidian:** Desktop Version (0.15.0 oder höher) +- **Node.js:** LTS Version (18+ empfohlen) - nur für Entwicklung +- **Git:** Für Repository-Zugriff (nur für Entwicklung) + +### Obsidian-Einstellungen + +- **Community Plugins:** Aktiviert +- **Restricted Mode:** Deaktiviert (für lokale Plugins) +- **Safe Mode:** Deaktiviert (für Plugin-Loading) + +--- + +## Installation + +### Option 1: Lokale Installation (Entwicklung) + +**Für Entwickler, die am Plugin arbeiten:** + +#### Schritt 1: Repository klonen + +```bash +git clone mindnet_obsidian +cd mindnet_obsidian +``` + +#### Schritt 2: Dependencies installieren + +```bash +npm install +``` + +#### Schritt 3: Build + +```bash +# Development Build (Watch Mode) +npm run dev + +# Oder Production Build +npm run build +``` + +#### Schritt 4: Deployment in Vault + +**Windows (PowerShell):** +```bash +npm run deploy:local +# oder +powershell -ExecutionPolicy Bypass -File scripts/deploy-local.ps1 +``` + +**Manuell:** +1. Erstelle Plugin-Ordner: `/.obsidian/plugins/mindnet-causal-assistant/` +2. Kopiere Dateien: + - `main.js` → Plugin-Ordner + - `manifest.json` → Plugin-Ordner + - Optional: `styles.css` → Plugin-Ordner (falls vorhanden) + +#### Schritt 5: Plugin aktivieren + +1. Öffne Obsidian +2. **Settings → Community Plugins** +3. Aktiviere "Mindnet Causal Assistant" +4. Plugin sollte jetzt geladen sein + +### Option 2: Community Plugin Installation (Zukunft) + +**Für Endnutzer (wenn Plugin im Community Store verfügbar):** + +1. Öffne Obsidian +2. **Settings → Community Plugins** +3. **Browse** → Suche "Mindnet Causal Assistant" +4. **Install** → **Enable** + +--- + +## Deployment + +### Lokales Deployment (Entwicklung) + +#### Automatisches Deployment (Windows) + +**PowerShell-Script:** `scripts/deploy-local.ps1` + +```powershell +# Script kopiert main.js, manifest.json nach Vault Plugin-Ordner +# Vault-Pfad muss in Script konfiguriert sein +``` + +**Verwendung:** +```bash +npm run deploy:local +``` + +#### Manuelles Deployment + +**Schritte:** +1. Build ausführen: `npm run build` +2. Plugin-Ordner erstellen: `/.obsidian/plugins/mindnet-causal-assistant/` +3. Dateien kopieren: + - `main.js` + - `manifest.json` + - Optional: `styles.css` +4. Obsidian Plugin reload (disable/enable) + +### Production Deployment + +#### Release-Prozess + +**Schritt 1: Version bumpen** + +```bash +npm version patch|minor|major +``` + +**Ergebnis:** +- `manifest.json` Version wird aktualisiert +- `package.json` Version wird aktualisiert +- `versions.json` Eintrag wird hinzugefügt + +**Schritt 2: Build** + +```bash +npm run build +``` + +**Ergebnis:** +- `main.js` wird erstellt (minified) +- TypeScript-Check wird ausgeführt + +**Schritt 3: Git Commit** + +```bash +git add manifest.json versions.json package.json +git commit -m "Release v1.0.1" +git tag v1.0.1 +git push origin main --tags +``` + +**Schritt 4: GitHub Release** + +1. Erstelle Release auf GitHub +2. **Tag:** `v1.0.1` (ohne `v` Prefix) +3. **Title:** `v1.0.1` +4. **Description:** Changelog +5. **Assets:** Upload `main.js`, `manifest.json`, optional `styles.css` + +--- + +## Konfiguration + +### Erste Konfiguration + +Nach der Installation müssen Konfigurationsdateien im Vault vorhanden sein: + +#### Standard-Pfade + +``` +_system/ + dictionary/ + edge_vocabulary.md + graph_schema.md + interview_config.yaml + chain_roles.yaml + chain_templates.yaml + analysis_policies.yaml +``` + +#### Plugin-Settings + +1. Öffne **Settings → Community Plugins → Mindnet Causal Assistant** +2. Prüfe Pfad-Settings: + - `edgeVocabularyPath`: `_system/dictionary/edge_vocabulary.md` + - `graphSchemaPath`: `_system/dictionary/graph_schema.md` + - `interviewConfigPath`: `_system/dictionary/interview_config.yaml` + - `chainRolesPath`: `_system/dictionary/chain_roles.yaml` + - `chainTemplatesPath`: `_system/dictionary/chain_templates.yaml` + +3. Passe Pfade an (falls abweichend) + +#### Config-Dateien erstellen + +**Falls Config-Dateien fehlen:** + +1. Erstelle Ordner: `_system/dictionary/` +2. Erstelle Config-Dateien (siehe Administratorhandbuch) +3. Plugin lädt Configs automatisch beim Start + +**Minimal-Beispiele:** + +**edge_vocabulary.md:** +```markdown +# Edge Vocabulary + +> [!edge-type] causes +> Canonical: causes +> Aliases: ausgelöst_durch +``` + +**interview_config.yaml:** +```yaml +version: "1.0" +frontmatter_whitelist: [] +profiles: + - key: experience_basic + note_type: experience + description: "Basic experience profile" + defaults: + folder: "" + steps: [] +``` + +**chain_roles.yaml:** +```yaml +version: "1.0" +roles: + causal: + edge_types: + - causes +``` + +**chain_templates.yaml:** +```yaml +version: "1.0" +defaults: + matching: + required_links: false +templates: [] +``` + +### Verifikation + +**Plugin-Status prüfen:** +1. Öffne DevTools (`Ctrl+Shift+I` / `Cmd+Option+I`) +2. Prüfe Console-Logs: + - `Vocabulary auto-loaded` + - `Interview config auto-loaded` + - `Chain roles loaded` + - `Chain templates loaded` + +**Commands testen:** +1. Command Palette (`Ctrl+P` / `Cmd+P`) +2. Suche "Mindnet" +3. Commands sollten verfügbar sein + +--- + +## Upgrade + +### Upgrade-Prozess + +#### Option 1: Lokales Upgrade (Entwicklung) + +**Schritte:** +1. Repository aktualisieren: + ```bash + git pull origin main + ``` +2. Dependencies aktualisieren (falls nötig): + ```bash + npm install + ``` +3. Build: + ```bash + npm run build + ``` +4. Deployment: + ```bash + npm run deploy:local + ``` +5. Obsidian Plugin reload (disable/enable) + +#### Option 2: Community Plugin Upgrade (Zukunft) + +**Automatisch:** +- Obsidian prüft automatisch auf Updates +- **Settings → Community Plugins → Updates** +- **Update** Button klicken + +**Manuell:** +- Plugin deinstallieren → neu installieren + +### Config-Migration + +**Bei größeren Version-Updates:** + +1. **Backup erstellen:** + - Config-Dateien sichern + - Vault-Backup erstellen + +2. **Changelog prüfen:** + - Breaking Changes beachten + - Config-Format-Änderungen prüfen + +3. **Configs aktualisieren:** + - Neue Felder hinzufügen (falls nötig) + - Deprecated Felder entfernen + +4. **Plugin neu laden:** + - Plugin disable/enable + - Console-Logs prüfen + +--- + +## Troubleshooting + +### Plugin lädt nicht + +**Symptom:** Plugin erscheint nicht in Settings oder zeigt Fehler. + +**Lösung:** +1. Prüfe Obsidian-Version (min. 0.15.0) +2. Prüfe `manifest.json` Syntax +3. Prüfe `main.js` Existenz im Plugin-Ordner +4. Prüfe Console-Logs (DevTools F12) +5. Obsidian neustarten +6. Plugin disable/enable + +### Config wird nicht geladen + +**Symptom:** Console zeigt "Config not found" oder Fehler. + +**Lösung:** +1. Prüfe Pfad in Settings +2. Prüfe Datei-Existenz im Vault +3. Prüfe Datei-Berechtigungen +4. Prüfe YAML-Syntax (für YAML-Dateien) +5. Prüfe Console-Logs für Details + +### Build-Fehler + +**Symptom:** `npm run build` schlägt fehl. + +**Lösung:** +1. Prüfe Node.js-Version (`node --version`) +2. Dependencies neu installieren: `npm install` +3. Prüfe TypeScript-Fehler: `npm run build` +4. Prüfe `tsconfig.json` Syntax +5. Prüfe `esbuild.config.mjs` Syntax + +### Deployment-Fehler + +**Symptom:** `deploy-local.ps1` schlägt fehl. + +**Lösung:** +1. Prüfe Vault-Pfad im Script +2. Prüfe PowerShell Execution Policy: + ```powershell + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + ``` +3. Manuelles Deployment versuchen +4. Prüfe Plugin-Ordner-Berechtigungen + +### Live-Reload funktioniert nicht + +**Symptom:** Config-Änderungen werden nicht übernommen. + +**Lösung:** +1. Prüfe Datei-Pfad (muss exakt mit Settings übereinstimmen) +2. Warte auf Debounce (200ms) +3. Manuelles Reload über Command +4. Plugin neu laden (disable/enable) + +### Commands erscheinen nicht + +**Symptom:** Commands sind nicht im Command Palette verfügbar. + +**Lösung:** +1. Prüfe Plugin-Status (aktiviert?) +2. Prüfe Console-Logs für Fehler +3. Obsidian neustarten +4. Command Palette neu öffnen (`Ctrl+P`) + +--- + +## Bekannte Probleme + +### Windows: PowerShell Execution Policy + +**Problem:** `deploy-local.ps1` wird blockiert. + +**Lösung:** +```powershell +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +``` + +### macOS/Linux: Permissions + +**Problem:** Plugin-Ordner kann nicht erstellt werden. + +**Lösung:** +- Prüfe Vault-Ordner-Berechtigungen +- Manuell Plugin-Ordner erstellen + +### Obsidian: Restricted Mode + +**Problem:** Plugin wird nicht geladen. + +**Lösung:** +- **Settings → Community Plugins → Restricted Mode** deaktivieren +- Für lokale Plugins erforderlich + +--- + +## Best Practices + +### Entwicklung + +1. **Watch Mode verwenden:** + ```bash + npm run dev + ``` + - Automatisches Rebuild bei Änderungen + - Source Maps für Debugging + +2. **Tests ausführen:** + ```bash + npm run test + ``` + - Vor jedem Commit + - Vor jedem Release + +3. **Linting:** + ```bash + npm run lint + ``` + - Code-Qualität prüfen + - Vor jedem Commit + +### Deployment + +1. **Backup erstellen:** + - Vor jedem Deployment + - Config-Dateien sichern + +2. **Staging testen:** + - Test-Vault verwenden + - Vor Production-Deployment + +3. **Versionierung:** + - SemVer verwenden + - Changelog führen + +### Wartung + +1. **Regelmäßige Updates:** + - Dependencies aktualisieren + - Obsidian API Updates prüfen + +2. **Monitoring:** + - Console-Logs prüfen + - User-Feedback sammeln + +3. **Dokumentation:** + - Änderungen dokumentieren + - Breaking Changes hervorheben + +--- + +## Weitere Ressourcen + +- **Benutzerhandbuch:** Endnutzer-Workflows +- **Administratorhandbuch:** Konfiguration und Wartung +- **Entwicklerhandbuch:** Code-Struktur und Erweiterungen +- **Architektur-Dokumentation:** System-Übersicht + +--- + +**Ende der Installation & Deployment Anleitung** diff --git a/docs/06_Konfigurationsdateien_Referenz.md b/docs/06_Konfigurationsdateien_Referenz.md new file mode 100644 index 0000000..40cd45b --- /dev/null +++ b/docs/06_Konfigurationsdateien_Referenz.md @@ -0,0 +1,644 @@ +# Mindnet Causal Assistant - Konfigurationsdateien Referenz + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Administratoren, Config-Manager + +--- + +## Inhaltsverzeichnis + +1. [Überblick](#überblick) +2. [Edge Vocabulary (`edge_vocabulary.md`)](#edge-vocabulary-edge_vocabularymd) +3. [Graph Schema (`graph_schema.md`)](#graph-schema-graph_schemamd) +4. [Interview Config (`interview_config.yaml`)](#interview-config-interview_configyaml) +5. [Chain Roles (`chain_roles.yaml`)](#chain-roles-chain_rolesyaml) +6. [Chain Templates (`chain_templates.yaml`)](#chain-templates-chain_templatesyaml) +7. [Analysis Policies (`analysis_policies.yaml`)](#analysis-policies-analysis_policiesyaml) + +--- + +## Überblick + +Das Mindnet Causal Assistant Plugin verwendet mehrere Konfigurationsdateien, die im Vault gespeichert werden. Diese Dateien definieren: + +- **Edge Vocabulary:** Kanonische Edge-Typen und Aliases +- **Graph Schema:** Empfehlungen für Edge-Typen basierend auf Note-Typen +- **Interview Config:** Profile, Steps, Loops für Note-Erstellung +- **Chain Roles:** Mapping von Edge-Typen zu kausalen Rollen +- **Chain Templates:** Vordefinierte Kettenmuster für Template Matching +- **Analysis Policies:** Policies für Findings (Severity, Unterdrückung) + +--- + +## Edge Vocabulary (`edge_vocabulary.md`) + +### Zweck + +Definiert kanonische Edge-Typen und ihre Aliases für Normalisierung und Lookup. + +### Format + +**Markdown-Datei** mit Tabellen-Struktur. + +### Struktur + +```markdown +# Edge Vocabulary + +### Kategorie 1 + +| System-Typ (Canonical) | Inverser Typ | Erlaubte Aliasse (User) | Beschreibung | Kategorie | +| :--- | :--- | :--- | :--- | :--- | +| **`causes`** | `caused_by` | `verursacht`, `führt_zu` | Direkte Kausalität | Kausal | +| **`caused_by`** | `causes` | `ausgelöst_durch`, `wegen` | Umgekehrte Kausalität | Kausal | + +### Kategorie 2 + +| System-Typ (Canonical) | Inverser Typ | Erlaubte Aliasse (User) | Beschreibung | Kategorie | +| :--- | :--- | :--- | :--- | :--- | +| **`influences`** | `influenced_by` | `beeinflusst`, `wirkt_auf` | Einfluss-Beziehung | Einfluss | +``` + +### Parsing-Regeln + +1. **H3-Überschriften (`###`)** werden als Kategorien erkannt +2. **Tabellen** werden geparst: + - Erste Spalte: Canonical Type (kann mit `**` fett formatiert sein) + - Zweite Spalte: Inverse Type (optional) + - Dritte Spalte: Aliases (komma-separiert, optional) + - Weitere Spalten: Beschreibung, Kategorie (optional) +3. **Backticked Tokens** (`\`type\``) werden extrahiert +4. **Header-Zeilen** werden übersprungen (enthält "Canonical", "System-Typ", etc.) +5. **Leere Zeilen** oder Zeilen ohne Tokens werden übersprungen + +### Beispiel + +```markdown +# Edge Vocabulary + +### Kausale Beziehungen + +| System-Typ (Canonical) | Inverser Typ | Erlaubte Aliasse (User) | Beschreibung | +| :--- | :--- | :--- | :--- | +| **`causes`** | `caused_by` | `verursacht`, `führt_zu` | Direkte Kausalität | +| **`caused_by`** | `causes` | `ausgelöst_durch`, `wegen` | Umgekehrte Kausalität | + +### Einfluss-Beziehungen + +| System-Typ (Canonical) | Inverser Typ | Erlaubte Aliasse (User) | Beschreibung | +| :--- | :--- | :--- | :--- | +| **`influences`** | `influenced_by` | `beeinflusst`, `wirkt_auf` | Einfluss-Beziehung | +``` + +### Verwendung + +- **Normalisierung:** `vocabulary.normalize("ausgelöst_durch")` → `{ canonical: "caused_by", inverse: "causes" }` +- **Lookup:** `vocabulary.getCanonical("verursacht")` → `"causes"` +- **Inverse:** `vocabulary.getInverse("causes")` → `"caused_by"` + +--- + +## Graph Schema (`graph_schema.md`) + +### Zweck + +Definiert Empfehlungen für Edge-Typen basierend auf Source- und Target-Note-Typen. + +### Format + +**Markdown-Datei** mit Sections und Tabellen. + +### Struktur + +```markdown +# Graph Schema + +## Source: `experience` + +| Target Type | Typical | Prohibited | +| :--- | :--- | :--- | +| `insight` | `causes`, `influences` | `part_of`, `instance_of` | +| `decision` | `influences` | `causes` | + +## Source: `insight` + +| Target Type | Typical | Prohibited | +| :--- | :--- | :--- | +| `decision` | `causes`, `enables` | `influences` | +``` + +### Parsing-Regeln + +1. **H2-Überschriften** mit Pattern `## Source: \`type\`` werden als Source-Typ erkannt +2. **Tabellen** werden geparst: + - Erste Spalte: Target Type (in Backticks) + - Zweite Spalte: Typical Edge Types (komma-separiert) + - Dritte Spalte: Prohibited Edge Types (komma-separiert) +3. **Header-Zeilen** werden übersprungen +4. **Leere Zeilen** werden übersprungen + +### Beispiel + +```markdown +# Graph Schema + +## Source: `experience` + +| Target Type | Typical | Prohibited | +| :--- | :--- | :--- | +| `insight` | `causes`, `influences` | `part_of` | +| `decision` | `influences` | `causes` | + +## Source: `insight` + +| Target Type | Typical | Prohibited | +| :--- | :--- | :--- | +| `decision` | `causes`, `enables` | `influences` | +``` + +### Verwendung + +- **Edge-Type-Selector:** Zeigt Empfehlungen basierend auf Source-Note-Type +- **Warnungen:** Zeigt Warnungen bei prohibited Types +- **Lookup:** `schema.getTypicalEdgeTypes("experience", "insight")` → `["causes", "influences"]` + +--- + +## Interview Config (`interview_config.yaml`) + +### Zweck + +Definiert Profile, Steps, Loops für Note-Erstellung und Interviews. + +### Format + +**YAML-Datei** mit strukturierter Hierarchie. + +### Struktur + +```yaml +version: "2.0" +frontmatter_whitelist: + - tags + - status + +profiles: + - key: experience_basic + label: "Erfahrung (Basis)" + note_type: experience + description: "Basic experience profile" + defaults: + folder: "experiences" + tags: ["experience"] + steps: + - id: context + prompt: "Beschreibe den Kontext" + input_type: textarea + required: true + - id: details + prompt: "Weitere Details" + input_type: textarea + required: false + post_run: + edger: true +``` + +### Felder + +#### Root-Level + +- **`version`** (string, optional): Config-Version (Standard: "2.0") +- **`frontmatter_whitelist`** (array of strings, optional): Erlaubte Frontmatter-Keys (zusätzlich zu Standard) +- **`profiles`** (array, required): Liste von Profilen + +#### Profile + +- **`key`** (string, required): Eindeutiger Profil-Schlüssel +- **`label`** (string, required): Anzeige-Name +- **`note_type`** (string, required): Note-Type (z.B. `experience`, `insight`, `decision`) +- **`description`** (string, optional): Beschreibung +- **`defaults`** (object, optional): Standardwerte + - **`folder`** (string, optional): Standard-Ordner + - **`tags`** (array of strings, optional): Standard-Tags + - Weitere Felder möglich +- **`steps`** (array, optional): Interview-Steps +- **`post_run`** (object, optional): Post-Run-Actions + - **`edger`** (boolean, optional): Semantic Mapping Builder ausführen + +#### Step + +- **`id`** (string, required): Eindeutige Step-ID +- **`prompt`** (string, required): Prompt-Text +- **`input_type`** (string, required): Input-Typ (`text`, `textarea`, `select`, etc.) +- **`required`** (boolean, optional): Ob Step erforderlich ist +- **`default`** (string, optional): Standardwert +- **`options`** (array, optional): Optionen für `select` Input-Type +- **`loop`** (object, optional): Loop-Konfiguration + - **`key`** (string, required): Loop-Key + - **`prompt`** (string, required): Loop-Prompt + - **`min_items`** (number, optional): Minimale Anzahl Items + - **`max_items`** (number, optional): Maximale Anzahl Items + - **`nested_loops`** (array, optional): Verschachtelte Loops + +### Beispiel + +```yaml +version: "2.0" +frontmatter_whitelist: + - tags + - status + +profiles: + - key: experience_basic + label: "Erfahrung (Basis)" + note_type: experience + description: "Basic experience profile" + defaults: + folder: "experiences" + tags: ["experience"] + steps: + - id: context + prompt: "Beschreibe den Kontext" + input_type: textarea + required: true + - id: events + prompt: "Wichtige Ereignisse" + input_type: textarea + loop: + key: events + prompt: "Ereignis" + min_items: 1 + max_items: 10 + post_run: + edger: true + + - key: insight_basic + label: "Einsicht (Basis)" + note_type: insight + defaults: + folder: "insights" + steps: + - id: insight + prompt: "Beschreibe die Einsicht" + input_type: textarea + required: true +``` + +### Verwendung + +- **Profil-Auswahl:** Profile werden in ProfileSelectionModal angezeigt +- **Wizard:** Steps werden als Wizard-Steps angezeigt +- **Frontmatter:** Frontmatter wird mit Whitelist generiert +- **Post-Run:** Actions werden nach Wizard ausgeführt + +--- + +## Chain Roles (`chain_roles.yaml`) + +### Zweck + +Mappt Edge-Typen zu kausalen Rollen für Template Matching. + +### Format + +**YAML-Datei** mit strukturierter Hierarchie. + +### Struktur + +```yaml +version: "1.0" + +roles: + causal: + description: "Direkte kausale Beziehungen" + edge_types: + - causes + - caused_by + - resulted_in + influences: + description: "Einfluss-Beziehungen" + edge_types: + - influences + - affects + enables_constraints: + description: "Ermöglicht/Beschränkt-Beziehungen" + edge_types: + - enables + - constrains + provenance: + description: "Herkunfts-Beziehungen" + edge_types: + - derived_from + - based_on +``` + +### Felder + +#### Root-Level + +- **`version`** (string, optional): Config-Version +- **`roles`** (object, required): Mapping von Rollen-Namen zu Rollen-Definitionen + +#### Role + +- **`description`** (string, optional): Beschreibung der Rolle +- **`edge_types`** (array of strings, required): Liste von Edge-Typen, die zu dieser Rolle gehören + +### Standard-Rollen + +- **`causal`:** Direkte kausale Beziehungen +- **`influences`:** Einfluss-Beziehungen +- **`enables_constraints`:** Ermöglicht/Beschränkt-Beziehungen +- **`provenance`:** Herkunfts-Beziehungen + +### Beispiel + +```yaml +version: "1.0" + +roles: + causal: + description: "Direkte kausale Beziehungen" + edge_types: + - causes + - caused_by + - resulted_in + - resulted_from + influences: + description: "Einfluss-Beziehungen" + edge_types: + - influences + - affects + - impacts + enables_constraints: + description: "Ermöglicht/Beschränkt-Beziehungen" + edge_types: + - enables + - constrains + - limits + provenance: + description: "Herkunfts-Beziehungen" + edge_types: + - derived_from + - based_on + - originates_from +``` + +### Verwendung + +- **Template Matching:** Edge-Typen werden zu Rollen gemappt für Link-Constraints +- **Findings:** `no_causal_roles` Finding wird generiert, wenn keine causal Rollen gefunden werden +- **Lookup:** `chainRoles.getRoleForEdgeType("causes")` → `"causal"` + +--- + +## Chain Templates (`chain_templates.yaml`) + +### Zweck + +Definiert vordefinierte Kettenmuster für Template Matching. + +### Format + +**YAML-Datei** mit strukturierter Hierarchie. + +### Struktur + +```yaml +version: "1.0" + +defaults: + matching: + required_links: false + +templates: + - name: trigger_transformation_outcome + description: "Causal chain template" + slots: + - id: trigger + allowed_node_types: ["experience"] + - id: transformation + allowed_node_types: ["insight"] + - id: outcome + allowed_node_types: ["decision"] + links: + - from: trigger + to: transformation + allowed_edge_roles: ["causal"] + - from: transformation + to: outcome + allowed_edge_roles: ["causal"] + matching: + required_links: true +``` + +### Felder + +#### Root-Level + +- **`version`** (string, optional): Config-Version +- **`defaults`** (object, optional): Standardwerte + - **`matching`** (object, optional): Standard-Matching-Parameter + - **`required_links`** (boolean, optional): Ob Links erforderlich sind (Standard: `false`) + - **`profiles`** (object, optional): Profil-spezifische Defaults + - **`discovery`** (object, optional): Discovery-Profil-Parameter + - **`decisioning`** (object, optional): Decisioning-Profil-Parameter +- **`templates`** (array, required): Liste von Templates + +#### Template + +- **`name`** (string, required): Template-Name +- **`description`** (string, optional): Beschreibung +- **`slots`** (array, required): Slot-Definitionen +- **`links`** (array, optional): Link-Constraints +- **`matching`** (object, optional): Matching-Parameter (überschreibt Defaults) + - **`required_links`** (boolean, optional): Ob Links erforderlich sind + +#### Slot + +- **`id`** (string, required): Slot-ID +- **`allowed_node_types`** (array of strings, required): Erlaubte Note-Types für diesen Slot + +#### Link + +- **`from`** (string, required): Source-Slot-ID +- **`to`** (string, required): Target-Slot-ID +- **`allowed_edge_roles`** (array of strings, required): Erlaubte Edge-Rollen + +### Beispiel + +```yaml +version: "1.0" + +defaults: + matching: + required_links: false + profiles: + discovery: + required_links: false + min_slots_filled_for_gap_findings: 1 + min_score_for_gap_findings: 0 + decisioning: + required_links: true + min_slots_filled_for_gap_findings: 2 + min_score_for_gap_findings: 10 + +templates: + - name: trigger_transformation_outcome + description: "Causal chain: trigger → transformation → outcome" + slots: + - id: trigger + allowed_node_types: ["experience", "event"] + - id: transformation + allowed_node_types: ["insight"] + - id: outcome + allowed_node_types: ["decision", "action"] + links: + - from: trigger + to: transformation + allowed_edge_roles: ["causal"] + - from: transformation + to: outcome + allowed_edge_roles: ["causal"] + matching: + required_links: true + + - name: loop_learning + description: "Learning loop: experience → learning → behavior → feedback" + slots: + - id: experience + allowed_node_types: ["experience"] + - id: learning + allowed_node_types: ["insight", "learning"] + - id: behavior + allowed_node_types: ["decision", "action"] + - id: feedback + allowed_node_types: ["experience", "event"] + links: + - from: experience + to: learning + allowed_edge_roles: ["causal", "influences"] + - from: learning + to: behavior + allowed_edge_roles: ["causal"] + - from: behavior + to: feedback + allowed_edge_roles: ["causal", "influences"] + - from: feedback + to: experience + allowed_edge_roles: ["causal", "influences"] +``` + +### Verwendung + +- **Template Matching:** Templates werden gegen lokalen Subgraph gematcht +- **Findings:** `missing_slot_*` Findings werden generiert, wenn Slots fehlen +- **Link Constraints:** `missing_link_constraints` Finding wird generiert, wenn Links fehlen (wenn `required_links=true`) + +--- + +## Analysis Policies (`analysis_policies.yaml`) + +### Zweck + +Definiert Policies für Findings (Severity, Unterdrückung, etc.). + +### Format + +**YAML-Datei** (geplant, noch nicht vollständig implementiert). + +### Geplante Struktur + +```yaml +version: "1.0" + +findings: + missing_slot_*: + default_severity: warn + profiles: + discovery: + severity: info + suppress_if: + - slots_filled < 2 + decisioning: + severity: warn + suppress_if: [] + dangling_target: + default_severity: error + suppress_if: [] + missing_link_constraints: + default_severity: warn + suppress_if: + - required_links == false + no_causal_roles: + default_severity: info + suppress_if: [] +``` + +### Felder (geplant) + +#### Root-Level + +- **`version`** (string, optional): Config-Version +- **`findings`** (object, required): Mapping von Finding-Codes zu Policies + +#### Finding Policy + +- **`default_severity`** (string, required): Standard-Severity (`error`, `warn`, `info`) +- **`profiles`** (object, optional): Profil-spezifische Overrides + - **`discovery`** (object, optional): Discovery-Profil-Parameter + - **`decisioning`** (object, optional): Decisioning-Profil-Parameter +- **`suppress_if`** (array, optional): Bedingungen für Unterdrückung + +### Status + +**Noch nicht vollständig implementiert.** Aktuell wird Severity-Policy teilweise in `severityPolicy.ts` gehandhabt. + +--- + +## Validierung & Fehlerbehandlung + +### YAML-Dateien + +- **Syntax-Fehler:** Werden beim Laden erkannt und geloggt +- **Last-Known-Good:** Letzte gültige Config wird bei Fehlern verwendet +- **Warnings:** Ungültige Felder werden als Warnings geloggt, nicht als Fehler + +### Markdown-Dateien + +- **Parsing-Fehler:** Werden beim Laden erkannt und geloggt +- **Fehlende Felder:** Werden ignoriert oder mit Defaults gefüllt +- **Warnings:** Ungültige Zeilen werden übersprungen + +### Live-Reload + +- **Debounced:** 200ms Delay für Performance +- **Automatisch:** Bei Dateiänderungen +- **Manuell:** Über Commands möglich + +--- + +## Best Practices + +### Versionierung + +- Verwenden Sie Versionsnummern in Config-Dateien +- Dokumentieren Sie Änderungen +- Testen Sie Änderungen in Test-Vault + +### Struktur + +- Verwenden Sie klare, konsistente Namen +- Kommentieren Sie komplexe Konfigurationen +- Gruppieren Sie verwandte Einträge + +### Wartung + +- Regelmäßige Backups +- Git-Versionierung empfohlen +- Dokumentation von Custom-Konfigurationen + +--- + +**Ende der Konfigurationsdateien Referenz** diff --git a/docs/07_Event_Handler_Commands.md b/docs/07_Event_Handler_Commands.md new file mode 100644 index 0000000..a82e879 --- /dev/null +++ b/docs/07_Event_Handler_Commands.md @@ -0,0 +1,528 @@ +# Mindnet Causal Assistant - Event Handler & Commands Referenz + +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Zielgruppe:** Entwickler, Administratoren + +--- + +## Inhaltsverzeichnis + +1. [Event Handler](#event-handler) +2. [Commands](#commands) +3. [Settings & Konfiguration](#settings--konfiguration) + +--- + +## Event Handler + +Das Plugin registriert mehrere Event Handler für automatische Funktionen: + +### 1. Vault Modify Event + +**Zweck:** Live-Reload von Konfigurationsdateien + +**Registriert:** `this.app.vault.on("modify", ...)` + +**Funktionsweise:** +- Überwacht alle Dateiänderungen im Vault +- Prüft, ob geänderte Datei einer Config-Datei entspricht +- Debounced Reload (200ms Delay) +- Lädt Config automatisch neu + +**Überwachte Dateien:** +- `edge_vocabulary.md` (via `edgeVocabularyPath`) +- `interview_config.yaml` (via `interviewConfigPath`) +- `graph_schema.md` (via `graphSchemaPath`) +- `chain_roles.yaml` (via `chainRolesPath`) +- `chain_templates.yaml` (via `chainTemplatesPath`) + +**Code:** +```typescript +this.registerEvent( + this.app.vault.on("modify", async (file: TFile) => { + // Prüft Datei-Pfad + // Debounced Reload + // Lädt Config neu + }) +); +``` + +### 2. Vault Create Event + +**Zweck:** Note Adoption für neu erstellte Notes + +**Registriert:** `this.app.vault.on("create", ...)` (nach `onLayoutReady`) + +**Funktionsweise:** +- Wird nur ausgeführt, wenn `adoptNewNotesInEditor` aktiviert ist +- Prüft, ob neue Datei ein Adopt-Candidate ist +- Evaluates Adoption Confidence +- Zeigt Adoption-Modal (abhängig von Confidence) +- Startet Profil-Auswahl + +**Bedingungen:** +- Datei muss `.md` Extension haben +- Datei darf nicht unter `.obsidian/` sein +- Datei muss klein sein (`adoptMaxChars`) +- Datei darf keine Frontmatter-ID haben + +**Code:** +```typescript +this.app.workspace.onLayoutReady(() => { + this.registerEvent( + this.app.vault.on("create", async (file: TFile) => { + await this.handleFileCreate(file); + }) + ); +}); +``` + +### 3. Markdown Post Processor + +**Zweck:** Unresolved Link Handling in Reading View + +**Registriert:** `this.registerMarkdownPostProcessor(...)` + +**Funktionsweise:** +- Wird nur ausgeführt, wenn `interceptUnresolvedLinkClicks` aktiviert ist +- Findet alle `a.internal-link` Elemente +- Prüft, ob Link unresolved ist +- Fügt Click-Handler hinzu +- Bypass-Modifier wird respektiert + +**Bypass-Modifier:** +- Standard: `Alt` (konfigurierbar via `bypassModifier`) +- Wenn gedrückt: Obsidian behandelt Link normal + +**Code:** +```typescript +this.registerMarkdownPostProcessor((el, ctx) => { + const links = Array.from(el.querySelectorAll("a.internal-link")); + for (const link of links) { + // Prüft unresolved + // Fügt Click-Handler hinzu + } +}); +``` + +### 4. DOM Click Event + +**Zweck:** Unresolved Link Handling in Editor (Live Preview/Source) + +**Registriert:** `this.registerDomEvent(document, "click", ...)` + +**Funktionsweise:** +- Wird nur ausgeführt, wenn `interceptUnresolvedLinkClicks` aktiviert ist +- Prüft, ob Follow-Modifier gedrückt ist +- Prüft, ob Cursor in Wikilink ist +- Prüft, ob Link unresolved ist +- Startet Profil-Auswahl + +**Follow-Modifier:** +- Standard: `Ctrl` (konfigurierbar via `editorFollowModifier`) +- Muss gedrückt sein, damit Handler aktiviert wird + +**Code:** +```typescript +this.registerDomEvent(document, "click", async (evt: MouseEvent) => { + // Prüft Follow-Modifier + // Prüft Cursor-Position + // Prüft Wikilink + // Startet Profil-Auswahl +}); +``` + +--- + +## Commands + +Das Plugin registriert 11 Commands: + +### 1. Mindnet: Reload edge vocabulary + +**ID:** `mindnet-reload-edge-vocabulary` + +**Typ:** Callback Command + +**Funktionsweise:** +- Lädt `edge_vocabulary.md` neu +- Parst Markdown zu EdgeVocabulary +- Erstellt neue Vocabulary-Instanz +- Aktualisiert Cache +- Zeigt Notice mit Stats + +**Verwendung:** +- Nach Änderungen an `edge_vocabulary.md` +- Für Debugging +- Manuelles Reload (falls automatisches Reload nicht funktioniert) + +### 2. Mindnet: Validate current note + +**ID:** `mindnet-validate-current-note` + +**Typ:** Callback Command + +**Funktionsweise:** +- Lädt Vocabulary (falls nicht geladen) +- Ruft `LintEngine.lintCurrentNote()` auf +- Zählt Findings nach Severity +- Zeigt Notice mit Summary +- Loggt Findings in Console + +**Settings:** +- `showCanonicalHints`: Zeigt Canonical-Hints als INFO-Findings + +**Output:** +- Notice: `"Lint: X errors, Y warnings, Z info"` +- Console: Detaillierte Findings-Liste + +### 3. Mindnet: Export graph + +**ID:** `mindnet-export-graph` + +**Typ:** Callback Command + +**Funktionsweise:** +- Lädt Vocabulary (falls nicht geladen) +- Baut Graph aus Vault +- Serialisiert zu JSON +- Schreibt Export-Datei +- Zeigt Notice + +**Settings:** +- `exportPath`: Pfad für Export-Datei (Standard: `_system/exports/graph_export.json`) + +**Output:** +- JSON-Datei mit Nodes und Edges +- Notice: `"Graph exported to "` + +### 4. Mindnet: Show chains from current note + +**ID:** `mindnet-show-chains-from-current-note` + +**Typ:** Callback Command + +**Funktionsweise:** +- Extrahiert Frontmatter-ID aus aktueller Note +- Baut Graph aus Vault +- Baut Index für Traversal +- Führt Traversal aus (forward/backward/both) +- Rendert Chain Report +- Schreibt Report-Datei +- Öffnet Report-Datei + +**Settings:** +- `chainDirection`: `"forward"` | `"backward"` | `"both"` +- `maxHops`: Maximale Anzahl Hops (Standard: 3) + +**Output:** +- Markdown-Report: `_system/exports/chain_report.md` +- Notice: `"Chains: X paths, Y nodes, Z warnings"` + +### 5. Mindnet: Create note from profile + +**ID:** `mindnet-create-note-from-profile` + +**Typ:** Callback Command + +**Funktionsweise:** +- Lädt Interview Config (falls nicht geladen) +- Prüft, ob Profile verfügbar sind +- Extrahiert initialen Titel aus Selection (falls vorhanden) +- Öffnet ProfileSelectionModal +- Erstellt Note nach Profil-Auswahl +- Startet Wizard (falls aktiviert) + +**Settings:** +- `autoStartInterviewOnCreate`: Ob Wizard automatisch startet +- `defaultNotesFolder`: Standard-Ordner für neue Notes + +**Workflow:** +1. Profile-Selection-Modal öffnet sich +2. Profil wählen +3. Titel eingeben +4. Ordner wählen (optional) +5. Note wird erstellt +6. Wizard startet (falls aktiviert) + +### 6. Mindnet: Edge-Type ändern + +**ID:** `mindnet-change-edge-type` + +**Typ:** Editor Callback Command + +**Funktionsweise:** +- Erkennt Kontext (Cursor-Position, Selection) +- Prüft, ob Kontext erkannt werden kann +- Ruft `changeEdgeTypeForLinks()` auf +- Zeigt Edge-Type-Selector +- Aktualisiert Links + +**Kontext-Modi:** +- `single-link`: Cursor in einem Link +- `selection-links`: Auswahl enthält Links +- `create-link`: Neuer Link soll erstellt werden +- `whole-note`: Ganze Note (falls kein spezifischer Kontext) + +**Settings:** +- `inlineMicroEnabled`: Inline Micro-Suggester aktivieren +- `inlineMaxAlternatives`: Maximale Anzahl Alternativen + +### 7. Mindnet: Debug Chain Roles (Loaded) + +**ID:** `mindnet-debug-chain-roles` + +**Typ:** Callback Command + +**Funktionsweise:** +- Lädt Chain Roles (falls nicht geladen) +- Formatiert Debug-Output +- Loggt in Console +- Zeigt Notice + +**Output:** +- Console: Detaillierte Debug-Info + - Resolved Path + - Status (loaded/error/using-last-known-good) + - Loaded At (Timestamp) + - Errors/Warnings + - Roles-Übersicht +- Notice: `"Chain roles debug info logged to console (F12)"` + +### 8. Mindnet: Debug Chain Templates (Loaded) + +**ID:** `mindnet-debug-chain-templates` + +**Typ:** Callback Command + +**Funktionsweise:** +- Lädt Chain Templates (falls nicht geladen) +- Formatiert Debug-Output +- Loggt in Console +- Zeigt Notice + +**Output:** +- Console: Detaillierte Debug-Info + - Resolved Path + - Status (loaded/error/using-last-known-good) + - Loaded At (Timestamp) + - Errors/Warnings + - Templates-Übersicht +- Notice: `"Chain templates debug info logged to console (F12)"` + +### 9. Mindnet: Fix Findings (Current Section) + +**ID:** `mindnet-fix-findings` + +**Typ:** Editor Callback Command + +**Funktionsweise:** +- Lädt Chain Roles (falls nicht geladen) +- Lädt Interview Config (falls nicht geladen) +- Ruft `executeFixFindings()` auf +- Analysiert aktuelle Section +- Generiert Findings +- Zeigt verfügbare Fix-Actions +- Führt ausgewählte Action aus + +**Fix-Actions:** +- **Create Missing Note:** Erstellt fehlende Note +- **Retarget Link:** Ersetzt Link zu existierender Note +- **Create Missing Heading:** Erstellt Heading in Target-Datei +- **Retarget to Existing Heading:** Ersetzt Link zu existierendem Heading +- **Promote Candidate Edge:** Befördert Candidate-Edge zu explizitem Edge + +**Settings:** +- `fixActions.createMissingNote.mode`: Modus für fehlende Notes +- `fixActions.createMissingNote.defaultTypeStrategy`: Strategie für Note-Type +- `fixActions.createMissingHeading.level`: Heading-Level +- `fixActions.promoteCandidate.keepOriginal`: Original behalten + +### 10. Mindnet: Inspect Chains (Current Section) + +**ID:** `mindnet-inspect-chains` + +**Typ:** Editor Callback Command + +**Funktionsweise:** +- Lädt Chain Roles (falls nicht geladen) +- Lädt Chain Templates (falls nicht geladen) +- Ruft `executeInspectChains()` auf +- Extrahiert Section-Context +- Baut Graph-Index +- Führt Traversal aus +- Führt Template Matching aus +- Generiert Findings +- Loggt Report in Console + +**Settings:** +- `chainInspectorIncludeCandidates`: Ob Candidate-Edges einbezogen werden +- `chainInspectorMaxTemplateMatches`: Maximale Anzahl Template Matches +- `templateMatchingProfile`: `"discovery"` | `"decisioning"` + +**Output:** +- Console: Detaillierter Chain Inspector Report + - Context (file, heading) + - Neighbors (incoming/outgoing) + - Paths (forward/backward) + - Template Matches + - Findings +- Notice: `"Chain inspection complete. Check console (F12) for report."` + +### 11. Mindnet: Build semantic mapping blocks (by section) + +**ID:** `mindnet-build-semantic-mappings` + +**Typ:** Editor Callback Command + +**Funktionsweise:** +- Erkennt Kontext (Cursor-Position, Selection) +- Falls spezifischer Kontext: Verwendet Edge-Type-Selector +- Sonst: Verarbeitet ganze Note +- Prüft, ob Overwrite erlaubt ist +- Ruft `buildSemanticMappings()` auf +- Extrahiert existierende Mappings +- Parst Sections +- Extrahiert Links +- Weist Edge-Types zu +- Baut Mapping-Blöcke +- Aktualisiert Note + +**Settings:** +- `mappingWrapperCalloutType`: Callout-Typ für Wrapper (Standard: `"abstract"`) +- `mappingWrapperTitle`: Titel für Wrapper (Standard: `"🕸️ Semantic Mapping"`) +- `mappingWrapperFolded`: Ob Wrapper gefaltet ist (Standard: `true`) +- `defaultEdgeType`: Standard-Edge-Type +- `unassignedHandling`: `"prompt"` | `"none"` | `"defaultType"` | `"advisor"` +- `allowOverwriteExistingMappings`: Ob existierende Mappings überschrieben werden dürfen + +**Output:** +- Notice: `"Sections: X processed, Y with mappings | Links: Z total | Mappings: A kept, B new"` + +--- + +## Settings & Konfiguration + +### Alle Settings + +| Setting | Typ | Standard | Beschreibung | +|---------|-----|----------|--------------| +| **Pfad-Settings** | +| `edgeVocabularyPath` | string | `"_system/dictionary/edge_vocabulary.md"` | Pfad zum Edge-Vokabular | +| `graphSchemaPath` | string | `"_system/dictionary/graph_schema.md"` | Pfad zum Graph-Schema | +| `interviewConfigPath` | string | `"_system/dictionary/interview_config.yaml"` | Pfad zur Interview-Config | +| `chainRolesPath` | string | `"_system/dictionary/chain_roles.yaml"` | Pfad zu Chain Roles | +| `chainTemplatesPath` | string | `"_system/dictionary/chain_templates.yaml"` | Pfad zu Chain Templates | +| `analysisPoliciesPath` | string | `"_system/dictionary/analysis_policies.yaml"` | Pfad zu Analysis Policies | +| **Graph & Chain Settings** | +| `maxHops` | number | `3` | Maximale Anzahl Hops für Traversal | +| `strictMode` | boolean | `false` | Strict Mode (noch nicht vollständig implementiert) | +| `showCanonicalHints` | boolean | `false` | Zeigt Canonical-Hints in Lint-Findings | +| `chainDirection` | string | `"forward"` | Traversal-Richtung: `"forward"` \| `"backward"` \| `"both"` | +| **Interview Settings** | +| `autoStartInterviewOnCreate` | boolean | `false` | Wizard automatisch nach Note-Erstellung starten | +| **Unresolved Link Settings** | +| `interceptUnresolvedLinkClicks` | boolean | `true` | Unresolved Links abfangen | +| `autoStartOnUnresolvedClick` | boolean | `true` | Wizard automatisch nach Link-Klick starten | +| `bypassModifier` | string | `"Alt"` | Bypass-Modifier für Reading View: `"Alt"` \| `"Ctrl"` \| `"Shift"` \| `"None"` | +| `editorFollowModifier` | string | `"Ctrl"` | Follow-Modifier für Editor: `"Alt"` \| `"Ctrl"` \| `"Shift"` \| `"None"` | +| `waitForFirstModifyAfterCreate` | boolean | `true` | Warten auf erste Änderung nach Erstellung (für Templater) | +| `waitForModifyTimeoutMs` | number | `1200` | Timeout für Warten auf Änderung (ms) | +| `debugLogging` | boolean | `false` | Debug-Logging für Unresolved Link Handling | +| **Note Adoption Settings** | +| `adoptNewNotesInEditor` | boolean | `true` | Neue Notes automatisch adoptieren | +| `adoptMaxChars` | number | `200` | Maximale Content-Länge für Adoption-Candidate | +| `adoptConfirmMode` | string | `"onlyLowConfidence"` | Adoption-Confirmation-Modus: `"always"` \| `"onlyLowConfidence"` \| `"never"` | +| `highConfidenceWindowMs` | number | `3000` | Zeitfenster für High-Confidence-Adoption (ms) | +| **Semantic Mapping Settings** | +| `mappingWrapperCalloutType` | string | `"abstract"` | Callout-Typ für Mapping-Wrapper | +| `mappingWrapperTitle` | string | `"🕸️ Semantic Mapping"` | Titel für Mapping-Wrapper | +| `mappingWrapperFolded` | boolean | `true` | Ob Mapping-Wrapper gefaltet ist | +| `defaultEdgeType` | string | `""` | Standard-Edge-Type | +| `unassignedHandling` | string | `"prompt"` | Handling für unzugewiesene Links: `"prompt"` \| `"none"` \| `"defaultType"` \| `"advisor"` | +| `allowOverwriteExistingMappings` | boolean | `false` | Existierende Mappings überschreiben dürfen | +| `defaultNotesFolder` | string | `""` | Standard-Ordner für neue Notes | +| **Inline Micro Edge Suggester Settings** | +| `inlineMicroEnabled` | boolean | `true` | Inline Micro-Suggester aktivieren | +| `inlineMaxAlternatives` | number | `6` | Maximale Anzahl Alternativen | +| `inlineCancelBehavior` | string | `"keep_link"` | Verhalten bei Cancel: `"keep_link"` | +| **Export Settings** | +| `exportPath` | string | `"_system/exports/graph_export.json"` | Pfad für Graph-Export | +| **Chain Inspector Settings** | +| `chainInspectorIncludeCandidates` | boolean | `false` | Candidate-Edges in Chain Inspector einbeziehen | +| `chainInspectorMaxTemplateMatches` | number | `3` | Maximale Anzahl Template Matches | +| `templateMatchingProfile` | string | `"discovery"` | Template-Matching-Profil: `"discovery"` \| `"decisioning"` | +| **Fix Actions Settings** | +| `fixActions.createMissingNote.mode` | string | `"skeleton_only"` | Modus für fehlende Notes: `"skeleton_only"` \| `"create_and_open_profile_picker"` \| `"create_and_start_wizard"` | +| `fixActions.createMissingNote.defaultTypeStrategy` | string | `"profile_picker"` | Strategie für Note-Type: `"profile_picker"` \| `"inference_then_picker"` \| `"default_concept_no_prompt"` | +| `fixActions.createMissingNote.includeZones` | string | `"none"` | Zonen einbeziehen: `"none"` \| `"note_links_only"` \| `"candidates_only"` \| `"both"` | +| `fixActions.createMissingHeading.level` | number | `2` | Heading-Level für neue Headings | +| `fixActions.promoteCandidate.keepOriginal` | boolean | `true` | Original bei Candidate-Promotion behalten | + +### Settings-Wirkungsweise + +#### Pfad-Settings + +**Wirkungsweise:** +- Werden beim Plugin-Start geladen +- Werden für Live-Reload verwendet +- Werden für Config-Loading verwendet +- Pfade sind vault-relativ (forward slashes) + +**Änderung:** +- Settings → Community Plugins → Mindnet Causal Assistant +- Pfad ändern +- Settings speichern +- Plugin lädt Config automatisch neu + +#### Feature-Settings + +**Wirkungsweise:** +- Steuern automatische Funktionen +- Werden bei jedem Aufruf geprüft +- Können zur Laufzeit geändert werden + +**Beispiele:** +- `interceptUnresolvedLinkClicks`: Aktiviert/deaktiviert Link-Intercept +- `adoptNewNotesInEditor`: Aktiviert/deaktiviert Note-Adoption +- `autoStartInterviewOnCreate`: Aktiviert/deaktiviert automatischen Wizard-Start + +#### Fix-Actions-Settings + +**Wirkungsweise:** +- Steuern Fix-Action-Verhalten +- Werden bei `executeFixFindings()` verwendet +- Bestimmen, welche Actions verfügbar sind + +**Beispiele:** +- `fixActions.createMissingNote.mode`: Bestimmt, wie fehlende Notes erstellt werden +- `fixActions.createMissingHeading.level`: Bestimmt Heading-Level für neue Headings + +--- + +## Zusammenfassung + +### Event Handler + +- **Vault Modify:** Live-Reload von Config-Dateien +- **Vault Create:** Note Adoption +- **Markdown Post Processor:** Unresolved Link Handling (Reading View) +- **DOM Click Event:** Unresolved Link Handling (Editor) + +### Commands + +- **11 Commands** registriert +- **3 Editor Commands:** Erfordern aktiven Editor +- **8 Callback Commands:** Können überall ausgeführt werden + +### Settings + +- **40+ Settings** verfügbar +- **6 Pfad-Settings:** Für Config-Dateien +- **34 Feature-Settings:** Für Funktionalität +- **Alle Settings** sind in Settings Tab konfigurierbar + +--- + +**Ende der Event Handler & Commands Referenz** diff --git a/docs/readme.md b/docs/readme.md index 771fda6..9d4e702 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,45 +1,232 @@ -# README — Mindnet Obsidian Plugin (MVP 1.0) +# Mindnet Causal Assistant - Dokumentation -## Überblick -Das Mindnet Obsidian Plugin ist ein Authoring-Tool, das dich dabei unterstützt: -- Mindnet-Notes strukturiert anzulegen (Frontmatter, IDs, Typen) -- Inhalte über konfigurierbare Interviews zu erfassen -- semantische Kanten (Edges) zu pflegen und zu validieren -- Links und Edge-Zuordnungen innerhalb einer Note section-basiert zu gruppieren (Semantic Mapping) +> **Version:** 1.0.0 +> **Stand:** 2025-01-XX +> **Übersicht:** Vollständige Dokumentation des Mindnet Causal Assistant Plugins -## Hauptkonzepte -- **Profile**: Auswahl eines “Erstell-Profils” (kann mehrere Interviews pro Note-Typ geben). -- **Interview Config (YAML)**: definiert Steps, Loops, Defaults, Frontmatter-Whitelist. -- **ID-first**: Mindnet-Graph arbeitet über Frontmatter `id` als Schlüssel. -- **Semantic Mapping**: links in einer Section werden Edge-Typen zugeordnet und als Callouts strukturiert. +--- -## Quickstart (User) -1) Plugin installieren (siehe Handbuch: Deployment) -2) Settings: - - `edge_vocabulary path` setzen - - `graph_schema path` setzen - - `interview_config path` setzen -3) Neue Note: - - Command: **Mindnet: Create note from profile** - - Profil wählen, Titel setzen, Folder wählen - - Wizard ausfüllen, Finish - - Edger läuft optional post-run und baut Semantic Mapping Blöcke +## Übersicht -## Commands (Auszug) -- Create/Interview: - - Mindnet: Create note from profile - - (Auto) Start Wizard nach Create (konfigurierbar) -- Mapping/Edges: - - Mindnet: Build semantic mapping blocks (by section) - - Mindnet: Reload edge vocabulary - - (post-run) Edger nach Interview Finish -- QA: - - Mindnet: Validate current note (Lint) -- Export/Graph: - - Mindnet: Export graph (JSON) - - Mindnet: Show chains from current note +Diese Dokumentation deckt alle Aspekte des **Mindnet Causal Assistant** Plugins ab - von der Installation über die Nutzung bis hin zur Entwicklung und Administration. -## Konfigurationsdateien (typisch im Vault) -- `_system/dictionary/edge_vocabulary.md` -- `_system/dictionary/graph_schema.md` -- `_system/dictionary/interview_config.yaml` +--- + +## Dokumente nach Zielgruppe + +### 👤 Endnutzer + +**Dokument:** [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md) + +**Inhalt:** +- Schnellstart +- Hauptfunktionen +- Workflows +- Commands im Detail +- Troubleshooting + +**Für:** Nutzer, die das Plugin verwenden möchten + +--- + +### ⚙️ Administratoren + +**Dokument:** [02_Administratorhandbuch.md](./02_Administratorhandbuch.md) + +**Inhalt:** +- Plugin-Konfiguration +- Konfigurationsdateien (YAML, Markdown) +- Pfad-Management +- Live-Reload +- Wartung & Troubleshooting + +**Für:** Administratoren, Config-Manager, Vault-Verwalter + +--- + +### 👨‍💻 Entwickler + +**Dokument:** [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md) + +**Inhalt:** +- Projekt-Struktur +- Entwicklungsumgebung +- Code-Architektur +- Hauptmodule +- Erweiterungen entwickeln +- Testing +- Build & Deployment + +**Für:** Entwickler, die am Plugin arbeiten oder es erweitern + +--- + +### 🏗️ Architekten + +**Dokument:** [04_Architektur.md](./04_Architektur.md) + +**Inhalt:** +- System-Überblick +- Architektur-Prinzipien +- Komponenten-Architektur +- Datenfluss +- Konfigurations-Management +- Erweiterbarkeit + +**Für:** Architekten, System-Designer, Entwickler + +--- + +### 📦 Installation & Deployment + +**Dokument:** [05_Installation_Deployment.md](./05_Installation_Deployment.md) + +**Inhalt:** +- Voraussetzungen +- Installation (lokal, Community Plugin) +- Deployment (Development, Production) +- Konfiguration +- Upgrade +- Troubleshooting + +**Für:** Administratoren, Entwickler, Erst-Installation + +--- + +## Spezialisierte Dokumentation + +### Chain Inspector Reports + +- [CHAIN_INSPECTOR_V0_REPORT.md](./CHAIN_INSPECTOR_V0_REPORT.md) - v0.0 Implementierung +- [CHAIN_INSPECTOR_V02_REPORT.md](./CHAIN_INSPECTOR_V02_REPORT.md) - v0.2 Features +- [CHAIN_INSPECTOR_V03_REPORT.md](./CHAIN_INSPECTOR_V03_REPORT.md) - v0.3 Features +- [CHAIN_INSPECTOR_V04_REPORT.md](./CHAIN_INSPECTOR_V04_REPORT.md) - v0.4 Template Matching +- [CHAIN_INSPECTOR_V042_REPORT.md](./CHAIN_INSPECTOR_V042_REPORT.md) - v0.4.2 Updates + +### Konzepte & Details + +- [02_causal_chain_retrieving.md](./02_causal_chain_retrieving.md) - Kausale Ketten-Retrieval +- [DANGLING_TARGET_CASES.md](./DANGLING_TARGET_CASES.md) - Dangling Target Findings +- [06_Konfigurationsdateien_Referenz.md](./06_Konfigurationsdateien_Referenz.md) - Vollständige Referenz aller Config-Dateien +- [07_Event_Handler_Commands.md](./07_Event_Handler_Commands.md) - Event Handler & Commands Referenz + +### Dokumentations-Index + +- [00_Dokumentations_Index.md](./00_Dokumentations_Index.md) - Vollständige Übersicht aller Dokumentationen + +### Legacy-Dokumentation + +- [readme.md](./readme.md) - MVP 1.0 Quickstart +- [Handbuch.md](./Handbuch.md) - MVP 1.0 Handbuch +- [TESTING_WITH_REAL_VAULT.md](./TESTING_WITH_REAL_VAULT.md) - Testing mit echtem Vault + +--- + +## Schnellzugriff nach Thema + +### Installation & Setup + +1. **Erste Installation:** [05_Installation_Deployment.md](./05_Installation_Deployment.md) → Installation +2. **Konfiguration:** [02_Administratorhandbuch.md](./02_Administratorhandbuch.md) → Plugin-Konfiguration +3. **Schnellstart:** [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md) → Schnellstart + +### Nutzung + +1. **Workflows:** [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md) → Workflows +2. **Commands:** [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md) → Commands im Detail +3. **Troubleshooting:** [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md) → Troubleshooting + +### Konfiguration + +1. **Config-Dateien:** [02_Administratorhandbuch.md](./02_Administratorhandbuch.md) → Konfigurationsdateien +2. **Pfad-Management:** [02_Administratorhandbuch.md](./02_Administratorhandbuch.md) → Pfad-Management +3. **Live-Reload:** [02_Administratorhandbuch.md](./02_Administratorhandbuch.md) → Live-Reload + +### Entwicklung + +1. **Setup:** [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md) → Entwicklungsumgebung +2. **Code-Struktur:** [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md) → Projekt-Struktur +3. **Erweiterungen:** [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md) → Erweiterungen entwickeln +4. **Testing:** [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md) → Testing + +### Architektur + +1. **System-Überblick:** [04_Architektur.md](./04_Architektur.md) → System-Überblick +2. **Komponenten:** [04_Architektur.md](./04_Architektur.md) → Komponenten-Architektur +3. **Datenfluss:** [04_Architektur.md](./04_Architektur.md) → Datenfluss + +--- + +## Dokumentations-Standards + +### Format + +- **Markdown:** Alle Dokumente in Markdown +- **Struktur:** Klare Hierarchie mit Inhaltsverzeichnis +- **Code-Beispiele:** Syntax-Highlighting +- **Tabellen:** Für strukturierte Informationen + +### Versionierung + +- **Version:** In jedem Dokument angegeben +- **Stand:** Datum der letzten Aktualisierung +- **Zielgruppe:** Klar definiert + +### Aktualisierung + +- **Bei Features:** Dokumentation aktualisieren +- **Bei Breaking Changes:** Changelog führen +- **Bei Bugfixes:** Troubleshooting aktualisieren + +--- + +## Beitragen zur Dokumentation + +### Verbesserungen + +1. **Fehler melden:** Issues erstellen +2. **Verbesserungen vorschlagen:** Pull Requests +3. **Ergänzungen:** Neue Abschnitte hinzufügen + +### Formatierung + +- **Markdown:** Standard Markdown-Syntax +- **Code-Blöcke:** Mit Sprach-Angabe +- **Tabellen:** Für strukturierte Daten +- **Links:** Relative Links zu anderen Dokumenten + +--- + +## Weitere Ressourcen + +### Externe Links + +- **Obsidian API:** https://docs.obsidian.md +- **Obsidian Plugin Guidelines:** https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines +- **TypeScript:** https://www.typescriptlang.org/ +- **esbuild:** https://esbuild.github.io/ + +### Interne Ressourcen + +- **Repository:** Siehe Haupt-README +- **Changelog:** Siehe Haupt-README +- **Issues:** GitHub Issues + +--- + +## Kontakt & Support + +### Fragen zur Dokumentation + +- **Issues:** GitHub Issues erstellen +- **Pull Requests:** Verbesserungen einreichen + +### Fragen zum Plugin + +- **Issues:** GitHub Issues erstellen +- **Discussions:** GitHub Discussions (falls verfügbar) + +--- + +**Letzte Aktualisierung:** 2025-01-XX +**Dokumentations-Version:** 1.0.0 diff --git a/src/analysis/chainInspector.ts b/src/analysis/chainInspector.ts index 4bf0875..46188b7 100644 --- a/src/analysis/chainInspector.ts +++ b/src/analysis/chainInspector.ts @@ -1063,6 +1063,15 @@ export async function inspectChains( // Add template-based findings with profile thresholds for (const match of templateMatches) { + // Find the template definition to check for template-level required_links override + const templateDef = chainTemplates?.templates?.find(t => t.name === match.templateName); + + // Determine effective required_links: template.matching > profile > defaults.matching > false + const effectiveRequiredLinks = templateDef?.matching?.required_links ?? + profile?.required_links ?? + chainTemplates?.defaults?.matching?.required_links ?? + false; + // missing_slot_ findings (with profile thresholds) if (match.missingSlots.length > 0) { const slotsFilled = Object.keys(match.slotAssignments).length; @@ -1086,7 +1095,9 @@ export async function inspectChains( } // missing_link_constraints finding - if (match.slotsComplete && match.requiredLinks > 0 && !match.linksComplete) { + // Only emit if required_links=true (strict mode) + // In soft mode (required_links=false), suppress this finding even if links are incomplete + if (effectiveRequiredLinks && match.slotsComplete && match.requiredLinks > 0 && !match.linksComplete) { findings.push({ code: "missing_link_constraints", severity: applySeverityPolicy(profileName as "discovery" | "decisioning" | undefined, "missing_link_constraints", "info"), diff --git a/src/tests/analysis/chainInspector.requiredLinks.test.ts b/src/tests/analysis/chainInspector.requiredLinks.test.ts new file mode 100644 index 0000000..11b57f7 --- /dev/null +++ b/src/tests/analysis/chainInspector.requiredLinks.test.ts @@ -0,0 +1,385 @@ +/** + * Tests for required_links suppression of missing_link_constraints findings. + */ + +import { describe, it, expect, vi, beforeEach } from "vitest"; +import type { App, TFile } from "obsidian"; +import { inspectChains } from "../../analysis/chainInspector"; +import type { SectionContext } from "../../analysis/sectionContext"; +import type { ChainRolesConfig, ChainTemplatesConfig } from "../../dictionary/types"; +import { parseEdgeVocabulary } from "../../vocab/parseEdgeVocabulary"; +import { VocabularyLoader } from "../../vocab/VocabularyLoader"; + +// Mock VocabularyLoader +vi.mock("../../vocab/VocabularyLoader", () => ({ + VocabularyLoader: { + loadText: vi.fn(), + }, +})); + +describe("Chain Inspector required_links suppression", () => { + let mockApp: App; + let mockFileA: TFile; + let mockFileB: TFile; + let mockFileC: TFile; + + beforeEach(() => { + mockFileA = { + path: "NoteA.md", + name: "NoteA.md", + extension: "md", + basename: "NoteA", + } as TFile; + + mockFileB = { + path: "NoteB.md", + name: "NoteB.md", + extension: "md", + basename: "NoteB", + } as TFile; + + mockFileC = { + path: "NoteC.md", + name: "NoteC.md", + extension: "md", + basename: "NoteC", + } as TFile; + + mockApp = { + vault: { + getAbstractFileByPath: vi.fn(), + read: vi.fn(), + getMarkdownFiles: vi.fn().mockReturnValue([]), + cachedRead: vi.fn(), + }, + metadataCache: { + getFileCache: vi.fn().mockReturnValue(null), + getFirstLinkpathDest: vi.fn().mockReturnValue(null), + getBacklinksForFile: vi.fn().mockReturnValue(new Map()) as any, + }, + } as unknown as App; + + vi.mocked(VocabularyLoader.loadText).mockResolvedValue(""); + }); + + it("should emit missing_link_constraints when required_links=true", async () => { + // Setup: Template match with slotsComplete=true, requiredLinks>0, but linksComplete=false + // We need both decision and insight nodes, and an edge between them + const contentA = `# Note A + +## Decision +Some decision content. + +> [!edge] causes +> [[NoteB]] +`; + + const contentB = `# Note B + +## Insight +Some insight content. +`; + + const chainRoles: ChainRolesConfig = { + roles: { + causal: { + edge_types: ["causes"], + }, + }, + }; + + const chainTemplates: ChainTemplatesConfig = { + defaults: { + profiles: { + decisioning: { + required_links: true, // Strict mode + min_slots_filled_for_gap_findings: 1, + min_score_for_gap_findings: 0, + }, + }, + }, + templates: [ + { + name: "decision_logic", + slots: ["decision", "insight"], + links: [ + { from: "decision", to: "insight" }, + ], + }, + ], + }; + + vi.mocked(mockApp.vault.getAbstractFileByPath).mockImplementation( + (path: string) => { + if (path === "NoteA.md") return mockFileA; + if (path === "NoteB.md") return mockFileB; + return null; + } + ); + vi.mocked(mockApp.vault.read).mockImplementation((file: TFile) => { + if (file.path === "NoteA.md") return Promise.resolve(contentA); + if (file.path === "NoteB.md") return Promise.resolve(contentB); + return Promise.resolve(""); + }); + + const context: SectionContext = { + file: "NoteA.md", + heading: "Decision", + zoneKind: "content", + sectionIndex: 1, + }; + + const report = await inspectChains( + mockApp, + context, + { + includeNoteLinks: true, + includeCandidates: false, + maxDepth: 3, + direction: "both", + }, + chainRoles, + undefined, + chainTemplates, + { + path: "_system/dictionary/chain_templates.yaml", + status: "loaded", + loadedAt: Date.now(), + templateCount: 1, + }, + "decisioning" + ); + + // Should have template match (if slots can be assigned) + expect(report.templateMatches).toBeDefined(); + + // Find match if it exists + const match = report.templateMatches?.find(m => m.templateName === "decision_logic"); + + // Only verify finding if we have a match with incomplete links + if (match && match.slotsComplete && match.requiredLinks > 0 && !match.linksComplete) { + // Verify report still includes link counts (transparency) + expect(match.satisfiedLinks).toBeDefined(); + expect(match.requiredLinks).toBeDefined(); + + // Should have missing_link_constraints finding (strict mode) + const missingLinkFinding = report.findings.find(f => f.code === "missing_link_constraints"); + expect(missingLinkFinding).toBeDefined(); + expect(missingLinkFinding?.message).toContain("decision_logic"); + expect(missingLinkFinding?.message).toContain("link constraints missing"); + } + + // Verify profile config + expect(report.templateMatchingProfileUsed?.profileConfig?.required_links).toBe(true); + }); + + it("should NOT emit missing_link_constraints when required_links=false", async () => { + // Setup: Same template match, but with required_links=false (soft mode) + const contentA = `# Note A + +## Decision +Some decision content. + +> [!edge] causes +> [[NoteB]] +`; + + const contentB = `# Note B + +## Insight +Some insight content. +`; + + const chainRoles: ChainRolesConfig = { + roles: { + causal: { + edge_types: ["causes"], + }, + }, + }; + + const chainTemplates: ChainTemplatesConfig = { + defaults: { + profiles: { + discovery: { + required_links: false, // Soft mode + min_slots_filled_for_gap_findings: 1, + min_score_for_gap_findings: 0, + }, + }, + }, + templates: [ + { + name: "decision_logic", + slots: ["decision", "insight"], + links: [ + { from: "decision", to: "insight" }, + ], + }, + ], + }; + + vi.mocked(mockApp.vault.getAbstractFileByPath).mockImplementation( + (path: string) => { + if (path === "NoteA.md") return mockFileA; + if (path === "NoteB.md") return mockFileB; + return null; + } + ); + vi.mocked(mockApp.vault.read).mockImplementation((file: TFile) => { + if (file.path === "NoteA.md") return Promise.resolve(contentA); + if (file.path === "NoteB.md") return Promise.resolve(contentB); + return Promise.resolve(""); + }); + + const context: SectionContext = { + file: "NoteA.md", + heading: "Decision", + zoneKind: "content", + sectionIndex: 1, + }; + + const report = await inspectChains( + mockApp, + context, + { + includeNoteLinks: true, + includeCandidates: false, + maxDepth: 3, + direction: "both", + }, + null, + undefined, + chainTemplates, + { + path: "_system/dictionary/chain_templates.yaml", + status: "loaded", + loadedAt: Date.now(), + templateCount: 1, + }, + "discovery" + ); + + // Should have template match (if slots can be assigned) + expect(report.templateMatches).toBeDefined(); + + // Find match if it exists + const match = report.templateMatches?.find(m => m.templateName === "decision_logic"); + + // Only verify finding suppression if we have a match with incomplete links + if (match && match.slotsComplete && match.requiredLinks > 0 && !match.linksComplete) { + // Verify report still includes link counts (transparency maintained) + expect(match.satisfiedLinks).toBeDefined(); + expect(match.requiredLinks).toBeDefined(); + + // Should NOT have missing_link_constraints finding (soft mode suppresses it) + const missingLinkFinding = report.findings.find(f => f.code === "missing_link_constraints"); + expect(missingLinkFinding).toBeUndefined(); + } + + // Verify profile config + expect(report.templateMatchingProfileUsed?.profileConfig?.required_links).toBe(false); + }); + + it("should respect template-level required_links override", async () => { + // Setup: Profile has required_links=false, but template overrides to true + const contentA = `# Note A + +## Decision +Some decision content. + +> [!edge] causes +> [[NoteB]] +`; + + const contentB = `# Note B + +## Insight +Some insight content. +`; + + const chainRoles: ChainRolesConfig = { + roles: { + causal: { + edge_types: ["causes"], + }, + }, + }; + + const chainTemplates: ChainTemplatesConfig = { + defaults: { + profiles: { + discovery: { + required_links: false, // Profile says soft mode + min_slots_filled_for_gap_findings: 1, + min_score_for_gap_findings: 0, + }, + }, + }, + templates: [ + { + name: "decision_logic", + slots: ["decision", "insight"], + links: [ + { from: "decision", to: "insight" }, + ], + matching: { + required_links: true, // Template overrides to strict mode + }, + }, + ], + }; + + vi.mocked(mockApp.vault.getAbstractFileByPath).mockImplementation( + (path: string) => { + if (path === "NoteA.md") return mockFileA; + if (path === "NoteB.md") return mockFileB; + return null; + } + ); + vi.mocked(mockApp.vault.read).mockImplementation((file: TFile) => { + if (file.path === "NoteA.md") return Promise.resolve(contentA); + if (file.path === "NoteB.md") return Promise.resolve(contentB); + return Promise.resolve(""); + }); + + const context: SectionContext = { + file: "NoteA.md", + heading: "Decision", + zoneKind: "content", + sectionIndex: 1, + }; + + const report = await inspectChains( + mockApp, + context, + { + includeNoteLinks: true, + includeCandidates: false, + maxDepth: 3, + direction: "both", + }, + null, + undefined, + chainTemplates, + { + path: "_system/dictionary/chain_templates.yaml", + status: "loaded", + loadedAt: Date.now(), + templateCount: 1, + }, + "discovery" + ); + + // Should have template match + expect(report.templateMatches).toBeDefined(); + const match = report.templateMatches?.find(m => m.templateName === "decision_logic"); + expect(match).toBeDefined(); + + if (match && match.slotsComplete && match.requiredLinks > 0 && !match.linksComplete) { + // Template-level override should make this strict, so finding should appear + const missingLinkFinding = report.findings.find(f => f.code === "missing_link_constraints"); + expect(missingLinkFinding).toBeDefined(); + } + }); +});