Update documentation and enhance chain inspection logic
Some checks are pending
Node.js build / build (20.x) (push) Waiting to run
Node.js build / build (22.x) (push) Waiting to run

- Revamped the README to provide comprehensive documentation for the Mindnet Causal Assistant plugin, including user, administrator, developer, and architect guides.
- Added specialized documentation sections for installation, deployment, and troubleshooting.
- Enhanced the chain inspection logic to determine effective required links based on template definitions, profiles, and defaults, improving the accuracy of findings related to link completeness.
This commit is contained in:
Lars 2026-01-20 11:34:58 +01:00
parent 86c88bc275
commit 74cacdd41d
12 changed files with 5381 additions and 41 deletions

View File

@ -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**

412
docs/01_Benutzerhandbuch.md Normal file
View File

@ -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**

View File

@ -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**

View File

@ -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

View File

@ -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 <repository-url> 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<void> {
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<void> {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings(): Promise<void> {
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<void> {
// 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<LintFinding[]> => {
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:**
```
<vault>/.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**

683
docs/04_Architektur.md Normal file
View File

@ -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<T> {
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<LintFinding[]>;
}
```
**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<string, unknown>;
}
```
**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**

View File

@ -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 <repository-url> 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: `<vault>/.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: `<vault>/.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**

View File

@ -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**

View File

@ -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 <path>"`
### 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**

View File

@ -1,45 +1,232 @@
# README — Mindnet Obsidian Plugin (MVP 1.0) # Mindnet Causal Assistant - Dokumentation
## Überblick > **Version:** 1.0.0
Das Mindnet Obsidian Plugin ist ein Authoring-Tool, das dich dabei unterstützt: > **Stand:** 2025-01-XX
- Mindnet-Notes strukturiert anzulegen (Frontmatter, IDs, Typen) > **Übersicht:** Vollständige Dokumentation des Mindnet Causal Assistant Plugins
- 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)
## 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) ## Übersicht
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
## Commands (Auszug) Diese Dokumentation deckt alle Aspekte des **Mindnet Causal Assistant** Plugins ab - von der Installation über die Nutzung bis hin zur Entwicklung und Administration.
- 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
## Konfigurationsdateien (typisch im Vault) ---
- `_system/dictionary/edge_vocabulary.md`
- `_system/dictionary/graph_schema.md` ## Dokumente nach Zielgruppe
- `_system/dictionary/interview_config.yaml`
### 👤 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

View File

@ -1063,6 +1063,15 @@ export async function inspectChains(
// Add template-based findings with profile thresholds // Add template-based findings with profile thresholds
for (const match of templateMatches) { 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_<slotId> findings (with profile thresholds) // missing_slot_<slotId> findings (with profile thresholds)
if (match.missingSlots.length > 0) { if (match.missingSlots.length > 0) {
const slotsFilled = Object.keys(match.slotAssignments).length; const slotsFilled = Object.keys(match.slotAssignments).length;
@ -1086,7 +1095,9 @@ export async function inspectChains(
} }
// missing_link_constraints finding // 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({ findings.push({
code: "missing_link_constraints", code: "missing_link_constraints",
severity: applySeverityPolicy(profileName as "discovery" | "decisioning" | undefined, "missing_link_constraints", "info"), severity: applySeverityPolicy(profileName as "discovery" | "decisioning" | undefined, "missing_link_constraints", "info"),

View File

@ -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();
}
});
});