# 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