--- id: pflichtenheft_obsidian_plugin_mindnet_assistant title: Pflichtenheft – Obsidian Plugin „Mindnet Causal Assistant“ type: specification status: draft created: 2026-01-13 lang: de --- # Pflichtenheft – Obsidian Plugin „Mindnet Causal Assistant“ ## 1. Zielsetzung Das Plugin unterstützt den Nutzer beim Erstellen und Pflegen eines narrativ-kausalen Wissensgraphen in Obsidian (Mindnet). Es bietet: - **Aktive Authoring-Unterstützung** (Guided Note Creation / Interview Flow) - **Kausalketten-Prüfung** (Chain Explorer, Vorwärts/Rückwärts) - **Linting + Auto-Fixes** (Graph-Hygiene, konsistente Kanten, Namensnormalisierung) - **Export/Integration** der strukturierten Graph-Daten für ein Retrieval-System (Qdrant + Graph-Index) ## 2. Kontext & Randbedingungen - Obsidian Vault enthält Notes als Markdown, jede Entität eine Datei. - Notes enthalten Frontmatter (`id,title,type,status,...`) und Edges in Callout-Blöcken. - Edge-Vokabular inklusive Aliasse & Inversen ist verfügbar (z.B. `edge_vocabulary.md`). - Der Graph soll später von Mindnet traversierbar sein (Vorwärts/Rückwärts über inverse Relationen). - Plugin muss offline nutzbar sein; optionale Backend/LLM-Integration ist konfigurierbar. ## 3. Begriffsdefinitionen - **Node**: eine Obsidian Markdown-Datei (Entität). - **Edge**: gerichtete Beziehung zwischen zwei Nodes (canonical edge type). - **Alias**: alternative Edge-Bezeichnung in Notes, die auf canonical mapped wird. - **Inverse**: Gegenkante zu einer Edge, laut Vokabular (z.B. `resulted_in` ⇄ `caused_by`). - **Hub/Index**: Note, die primär navigiert (typisch `type: insight`), keine Kausalursache. ## 4. Scope ### In Scope (MVP → V2) **MVP** - Parser für Frontmatter + Edge-Callouts - Normalizer: Alias → Canonical; optional Inversen-Erkennung - Linter: Regelset (Error/Warn/Info) + Report - Chain Explorer: forward/backward traversal (1–4 hops) ab aktueller Note - Quickfixes: Edge-Typ ersetzen, Links normalisieren, Missing Note Stub erzeugen **V2** - Guided Authoring (Interview Flow) für `experience/decision/principle/state/strategy` - Refactor Mode: Text → Node/Edge-Kandidaten + Review UI - Export/Sync: JSON Graph Export + optional Qdrant Sync (separater Service) ### Out of Scope (initial) - Vollautomatische Kausalitäts-Interpretation ohne User-Bestätigung - Vollständige UI-Graph-Visualisierung (Obsidian Graph View bleibt nutzbar) - Direkte medizinische/psychologische Beratung ## 5. Nutzerrollen & Use Cases ### Rolle: Nutzer (Author) - UC1: „Ich schreibe eine Note und will Kanten prüfen“ - UC2: „Ich will von einem Ereignis aus die Kausalkette sehen“ - UC3: „Ich will eine neue Experience/Decision Note sauber anlegen“ - UC4: „Ich habe Text und will daraus Kandidaten extrahieren“ - UC5: „Ich will leere Links als open_question sauber erzeugen“ ### Rolle: System/Indexer (Mindnet) - UC6: „Ich brauche exportierbare adjacency lists + canonical edges“ ## 6. Funktionale Anforderungen (FR) ### FR1: Vault Parsing - FR1.1 Parse Frontmatter (YAML): `id,title,type,status,date,tags,...` - FR1.2 Parse Edge-Callouts im Format: - `> [!abstract]- 🕸️ Semantic Mapping` - `>> [!edge] ` - `>> [[target]]` - FR1.3 Extrahiere alle WikiLinks `[[...]]` aus Edge-Blocks - FR1.4 Erkenne Datei-Pfade, Dateinamen und canonical node identifiers (Dateiname ohne `.md`) **Output (intern)** ```ts type Node = { id?: string; title?: string; type?: string; status?: string; path: string; slug: string }; type Edge = { srcSlug: string; dstSlug: string; rawType: string; canonicalType?: string; line?: number; blockId?: string }; ``` ### FR2: Edge Normalization - FR2.1 Map rawType/Alias auf canonical edge type via Edge Vocabulary - FR2.2 Speichere Mapping-Entscheidungen (raw → canonical) pro Edge - FR2.3 Liefere inverse edge type (`inverseType`) pro canonical edge type (sofern definiert) ### FR3: Linting - FR3.1 Führe Checkliste von Regeln aus (siehe separates Dokument) - FR3.2 Liefere LintReport mit Severity (ERROR/WARN/INFO), Location (file, line), Fix-Vorschlägen - FR3.3 Quickfix: wende Fix auf Note an (Text edit), mit Preview/Diff ### FR4: Chain Explorer (Traversal) - FR4.1 Startpunkt: aktuelle Note im Editor - FR4.2 Forward traversal: `resulted_in`, `followed_by`, `impacts`, `source_of`, optional `related_to` - FR4.3 Backward traversal: `caused_by`, `preceeded_by`, `derived_from`, `impacted_by` - FR4.4 Konfigurierbare maxHops (Default 3) - FR4.5 Ergebnis als Liste von Pfaden + kompaktes Subgraph-Summary (Nodes/Edges) ### FR5: Missing Notes / Stubs - FR5.1 Erkenne, wenn Edge-Target nicht existiert - FR5.2 Biete „Create Stub Note“ an: - Template basierend auf Typ (default `open_question` wenn unbekannt) - Einhaltung Naming-Rules: `a-z0-9_` - FR5.3 Optional: convert TODO-Link → open_question note ### FR6: Guided Authoring (V2) - FR6.1 Wizard für neue Notes: Auswahl Typ → Fragen (eine nach der anderen) - FR6.2 Wizard erstellt Datei mit Template + initialen Edge-Blocks - FR6.3 Jede automatische Edge-Vermutung ist „review-required“ ### FR7: Refactor Mode (V2) - FR7.1 Extrahiere aus aktuellem Note-Text Kandidaten: - Event-Kandidaten (Datum/Ort/Verben) - Decision-Kandidaten („entschied“, „nahm an“, „wechselte“) - Principle-Kandidaten („ich glaube“, „ich habe gelernt“) - Relation-Kandidaten („dadurch“, „führte zu“, „weil“) - FR7.2 UI-Review: Checkbox-Liste zum Erstellen/Verwerfen - FR7.3 Generiere Notes + Edges nur nach Bestätigung ### FR8: Export (MVP optional / V2 empfohlen) - FR8.1 Export JSON: Nodes + canonical edges + inverses - FR8.2 Export adjacency list pro node slug - FR8.3 Optional: webhook/CLI hook für Indexer (Qdrant) ## 7. Nicht-funktionale Anforderungen (NFR) - NFR1: Performant bei 10k Notes (incremental parse, caching) - NFR2: Offline-first; LLM/Backend optional - NFR3: Deterministische Normalisierung (gleiches Input → gleiches Output) - NFR4: Kein Erfinden von Fakten: Auto-Edge nur als Vorschlag - NFR5: Sicheres Editieren (Diff/Undo via Obsidian APIs) - NFR6: Konfigurierbarkeit (YAML/Settings Tab): maxHops, allowed edges, strict mode ## 8. Technisches Lösungsdesign ### 8.1 Obsidian Plugin Struktur (TypeScript) - `main.ts` – Plugin lifecycle, commands, views - `settings.ts` – Einstellungen - `parser/` – Markdown + callout parser - `graph/` – Node/Edge model, normalization, traversal - `lint/` – Rules engine, reports, quickfixes - `ui/` – Sidebar view, modals, diff preview ### 8.2 Speicherung / Cache - In-memory cache: map `path → parsed Node + edges + hash` - Incremental update: on file change events re-parse only changed file - Optional persisted cache in `.obsidian/plugins/.../cache.json` ### 8.3 Edge Vocabulary Integration - Input: `edge_vocabulary.md` im Vault ODER eingebettete JSON Ressource - Parsing: - canonical edge types - alias list - inverse mapping - Fallback: minimal builtin vocabulary, wenn Datei fehlt ### 8.4 Traversal Engine - Graph Index: adjacency lists aus canonical edges - Traversal: - BFS mit hop limit - optional weighted expansion (für Chain Explorer „relevant paths first“) ### 8.5 Quickfix Engine - Applies patches auf Markdown: - Replace edge type token im Callout (`>> [!edge] ...`) - Rename link targets (replace `[[old]]` → `[[new]]`) - Insert stub note file from template - Safety: - Show diff modal - Use Obsidian editor transactions / file API ### 8.6 Optional Backend / LLM (V2) - Backend (local node service) für: - text extraction (Refactor Mode) - suggestion generation - Communication: - HTTP local (`127.0.0.1`) oder WebSocket - API key storage via Obsidian settings (encrypted if possible) - Claude-code/Cursor: nutzt Code-Agent für Implementierung, nicht zur Runtime. ## 9. UI/UX Anforderungen ### 9.1 Sidebar View „Mindnet Assistant“ Tabs: - **Validate**: Lint Report + Fix Buttons - **Chains**: Forward/Backward Chain Explorer + Copy as text - **Create** (V2): Wizard new note - **Refactor** (V2): Extract candidates ### 9.2 Commands (Command Palette) - `Mindnet: Validate current note` - `Mindnet: Validate vault (selected folders)` - `Mindnet: Show chains from current note` - `Mindnet: Normalize edges in current note` - `Mindnet: Create stub for missing links` - (V2) `Mindnet: Start guided authoring` - (V2) `Mindnet: Refactor current note to graph` ## 10. Akzeptanzkriterien - AK1: Plugin erkennt Edge-Callouts und normalisiert Aliasse deterministisch - AK2: Linter findet Node-Splitting (mindestens Levenshtein/ähnliche Slugs) und Missing Notes - AK3: Chain Explorer liefert identische Pfade vorwärts/rückwärts bei inversen Edge-Paaren - AK4: Quickfix ersetzt Edge-Typen ohne Markdown zu zerstören; Undo funktioniert - AK5: Export JSON enthält canonical edges + inverse types ## 11. Deliverables - Obsidian Plugin (TS) mit MVP Features - Dokumentation: - Install/Build - Settings - Rule reference - Example vault sample - Optional: JSON Export Format Spec (nodes/edges) --- ## 12. Prompts für Code-Agenten (Cursor / Claude-code) ### Prompt A (Repo Scaffold + MVP) > Du bist ein Senior TypeScript Engineer. Implementiere ein Obsidian Plugin „Mindnet Causal Assistant“. > Ziele MVP: > 1) Parse Frontmatter (YAML) und Edge-Callouts im Format: > `> [!abstract]- 🕸️ Semantic Mapping` → `>> [!edge] ` → `>> [[target]]`. > 2) Normalisiere Edge Aliasse auf canonical edge types (Vokabular als JSON im Code; später ersetzbar). > 3) Baue eine Sidebar View mit Tabs „Validate“ und „Chains“. > 4) Implementiere Lint Regeln: missing target note, alias-not-normalized, hub-has-causal-edge, chronology-vs-causality warning. > 5) Implementiere Chain Explorer (forward/backward, maxHops=3). > 6) Implementiere Quickfix: replace edge type token, create stub note. > Nutze Obsidian APIs, schreibe sauberen TS Code, mit Tests für Parser/Normalizer. ### Prompt B (Parser Unit Tests) > Schreibe Unit Tests für den Markdown Parser: > - erkennt mehrere Edge-Blocks pro Datei > - erkennt mehrere Targets pro Edge > - liefert line numbers > - ignoriert WikiLinks außerhalb der Semantic Mapping Callouts > Nutze vitest/jest. Erzeuge fixtures. ### Prompt C (Lint Engine + Quickfix) > Implementiere eine Lint Engine als Rule-Pipeline. > Jede Regel: id, severity, detect(node, graph) -> findings, fix(finding)->patch. > Baue eine Diff Preview Modal und applyPatch über Obsidian file API. > Implementiere zunächst 6 Regeln aus der Checkliste. ### Prompt D (Vocabulary Loader) > Implementiere einen VocabularyLoader: > - lädt entweder eingebettetes JSON oder eine Vault-Datei `edge_vocabulary.md` > - parst canonical types, aliases, inverse > - bietet getCanonical(raw) und getInverse(canonical) > Fallback auf builtin vocabulary wenn parsing fehlschlägt.