- 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.
16 KiB
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 / Herkunftsection: Edge ist “voll gültig” für die Sectioncandidate: 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 mitscope: candidateim effektiven Graphen ausgefiltert. - Wenn
includeCandidates=true, werden Kandidatenkanten als incoming/outgoing berücksichtigt und tauchen inneighbors/pathsauf.
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_constraintswurde teilweise auch dann ausgegeben, wennrequired_links=false(Soft Mode) aktiv war → unnötig “noisy”.
Fix (laut Cursor-Report umgesetzt + Tests):
missing_link_constraintswird nur erzeugt, wenneffectiveRequiredLinks === true.- Es gibt eine definierte Auflösungsreihenfolge für
required_links:
Resolution Order (effective required_links):
template.matching?.required_linksprofile.required_linksdefaults.matching?.required_links- Fallback:
false
Transparenz bleibt erhalten:
satisfiedLinksundrequiredLinkswerden weiterhin im Report angezeigt.linksCompletebleibt als technischer Wert im Report bestehen.- Nur das Finding
missing_link_constraintswird 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_rolesoder 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: noteim 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_outcomeloop_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_findingsmin_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_rolesFinding- 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_constraintsnur 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: candidateaus 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_connectivitywenn nur incoming oder nur outgoingno_causal_roleswenn Edges da, aber keine causal Rollen im effektiven Graphmissing_link_constraintsnur 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
- Kandidaten finden (Slots)
- 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):
- In
02_event_trigger_detail.mdeinen klaren Note-Level Block definieren (z.B. “## Note-Verbindungen”). - Edge dort definieren, die auf eine andere Note/Section zeigt.
- Cursor in einer anderen Section derselben Note platzieren (z.B. “## Detail” oder “## Extra”).
- Chain Inspector laufen lassen.
- 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=falseaberrequired_links=falseund keinmissing_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=0bei includeCandidates=false, aber incoming candidate-edge existiert
→ Filter funktioniert wie geplant.
ENDE