diff --git a/config/decision_engine.yaml b/config/decision_engine.yaml index b69831b..674af21 100644 --- a/config/decision_engine.yaml +++ b/config/decision_engine.yaml @@ -32,7 +32,7 @@ streams_library: top_k: 5 edge_boosts: guides: 3.0 - enforced_by: 2.5 + depends_on: 2.5 based_on: 2.0 facts_stream: diff --git a/docs/02_concepts/02_causal_chain_retrieving.md b/docs/02_concepts/02_causal_chain_retrieving.md new file mode 100644 index 0000000..7c3ea1e --- /dev/null +++ b/docs/02_concepts/02_causal_chain_retrieving.md @@ -0,0 +1,394 @@ +# Mindnet Causal Assistant – Dokumentation der bisher erreichten Resultate (0.4.x) + Architektur, Konfiguration & Strategien + +> Stand: basierend auf den beobachteten Chain-Inspector-Logs und den zuletzt beschriebenen Implementierungen in 0.4.6/0.4.x. +> Ziel dieser Doku: Eine **einheitliche, belastbare Basis**, damit Weiterentwicklung (0.5.x/0.6.x) nicht mehr “im Kreis” läuft. + +--- + +## 1) Zweck & Gesamtziel von Mindnet + +Mindnet soll in einem Obsidian Vault **kausale/argumentative Zusammenhänge** als Graph abbilden und daraus **nützliche Diagnosen** ableiten: + +- **Graph-Aufbau:** Notes/Sections als Knoten, Links/Kanten als gerichtete Beziehungen (z.B. *wirkt_auf*, *resulted_in*, *depends_on* …). +- **Analyse aus einem Kontext:** Nutzer steht in einer Note an einer bestimmten Überschrift/Section → Mindnet analysiert lokale Nachbarschaft + Pfade im Graphen. +- **Template Matching:** Einordnen der gefundenen Knoten/Kanten in “Kettenmuster” (Chain Templates) wie z.B. *trigger → transformation → outcome* oder *loop_learning*. +- **Findings (Gap-Heuristiken):** Hinweise wie “fehlende Slots”, “fehlende Links”, “unmapped edge types”, “einseitige Konnektivität”, etc. + → Ziel: **Nutzer konkret zum besseren Graphen führen**, ohne “Noisy” zu sein. + +--- + +## 2) Begriffe & Datenmodell (so arbeitet der Chain Inspector) + +### 2.1 Kontext (Context) +Der Chain Inspector läuft immer gegen einen **aktuellen Kontext**: +- `file`: aktuelle Note (z.B. `Tests/03_insight_transformation.md`) +- `heading`: aktuelle Section (z.B. `Kern`) +- `zoneKind`: i.d.R. `content` + +Das ist wichtig, weil Kanten teils **section-spezifisch** sind und teils (geplant/teilweise offen) **note-weit** gelten könnten. + +--- + +### 2.2 Knoten (Nodes) +Ein Knoten ist im Report meist referenziert als: +- `file + heading` (z.B. `Tests/01_experience_trigger.md:Kontext`) +- plus abgeleitete Metadaten wie `noteType` (z.B. experience, insight, decision, event) + +**noteType** ist entscheidend fürs Template Matching (Slots). + +--- + +### 2.3 Kanten (Edges) +Eine Kante hat typischerweise: +- `rawEdgeType`: Original-Typ aus Markdown/Notation (z.B. `wirkt_auf`, `resulted_in`, `depends_on`, `derived_from`, …) +- `from`: Quelle (file:heading) +- `to`: Ziel (file:heading) +- `scope`: Gültigkeit / Herkunft + - `section`: Edge ist “voll gültig” für die Section + - `candidate`: Edge ist nur Kandidat/unsicher, wird optional zugelassen + - (geplant/offen) `note`: Edge gilt note-weit (unabhängig von Section) +- `evidence`: Fundstelle (file, sectionHeading, lineRange) + +--- + +## 3) Erreichte Resultate in 0.4.x (verifiziert) + +### 3.1 includeCandidates – Kandidatenkanten funktionieren wie erwartet +**Ergebnis (bereits mehrfach in Logs verifiziert):** +- Wenn `includeCandidates=false`, werden Kanten mit `scope: candidate` **im effektiven Graphen ausgefiltert**. +- Wenn `includeCandidates=true`, werden Kandidatenkanten **als incoming/outgoing** berücksichtigt und tauchen in `neighbors`/`paths` auf. + +**Implikation:** +- Das System kann “unsichere” oder “LLM-vorschlagene” Verbindungen existieren lassen, ohne in jedem Lauf die Analyse zu verfälschen. +- In “Discovery” kann man Kandidaten zulassen (mehr Explorationspower). +- In “Decisioning” kann man Kandidaten typischerweise sperren (mehr Verlässlichkeit). + +--- + +### 3.2 required_links: Strict vs Soft Mode – missing_link_constraints Unterdrückung ist umgesetzt +**Problem (historisch):** +- `missing_link_constraints` wurde teilweise auch dann ausgegeben, wenn `required_links=false` (Soft Mode) aktiv war → unnötig “noisy”. + +**Fix (laut Cursor-Report umgesetzt + Tests):** +- `missing_link_constraints` wird nur erzeugt, wenn `effectiveRequiredLinks === true`. +- Es gibt eine definierte Auflösungsreihenfolge für `required_links`: + +**Resolution Order (effective required_links):** +1. `template.matching?.required_links` +2. `profile.required_links` +3. `defaults.matching?.required_links` +4. Fallback: `false` + +**Transparenz bleibt erhalten:** +- `satisfiedLinks` und `requiredLinks` werden weiterhin im Report angezeigt. +- `linksComplete` bleibt als technischer Wert im Report bestehen. +- **Nur** das Finding `missing_link_constraints` wird unterdrückt, nicht die Fakten. + +**Implikation:** +- Soft Mode (= required_links=false) ist jetzt ruhig genug, um “Entdeckung” zu unterstützen. +- Strict Mode (= required_links=true) eignet sich für harte Qualitätskontrolle. + +--- + +### 3.3 “Healthy graph” → Findings leer ([]), Template “confirmed” +Wenn Slots **und** geforderte Links erfüllt sind (z.B. `trigger_transformation_outcome` mit 2/2 Links), +dann ist `findings: []` das erwartete Ergebnis. + +**Implikation:** +- Das ist das zentrale “Green Path”-Signal: Graph ist konsistent für das gewählte Template/Profil. + +--- + +### 3.4 Unmapped edges werden erkannt (Diagnose) +Wenn ein `rawEdgeType` nicht in die kanonischen Rollen/Edge-Rollen abgebildet werden kann, tauchen typischerweise Diagnosen auf: +- `edgesUnmapped > 0` +- Findings wie `no_causal_roles` oder link constraints bleiben unerfüllt + +**Implikation:** +- Das Rollen-Mapping (chain_roles.yaml) ist “critical path”: wenn ein Edge-Typ nicht gemappt wird, bricht oft der kausale Interpretationspfad. + +--- + +## 4) Was ist (noch) offen – echtes nächstes Verifikationsziel + +### 4.1 Note-Level Edges / Note-Scope (“für jede Sektion gültig”) +Es existiert ein Konzept/Einbau: In `02_event_trigger_detail` gibt es einen Bereich, der Kanten **auf Note-Ebene** definieren soll (unabhängig von aktueller Section). + +**Offen ist die robuste Verifikation (oder Implementierung), dass:** +- diese Edges auch dann gelten, wenn der Cursor in einer anderen Section derselben Note steht, +- idealerweise mit klar erkennbarer Kennzeichnung wie `scope: note` im Report. + +**Warum ist das wichtig?** +- Das ermöglicht “globaler Kontext” pro Note, ohne alles in jede Section duplizieren zu müssen. +- Es ist eine UX-Optimierung: Nutzer kann “Meta-Verbindungen” an einer Stelle pflegen. + +--- + +## 5) Konfigurationsdateien – Rolle & Interpretation (Mindnet-Strategie) + +> Die folgenden Bereiche beschreiben eine **saubere, konsistente Interpretation**, wie Mindnet die Configs verwenden sollte. +> Konkrete Keys, die in Logs sichtbar waren (z.B. required_links, min_slots_filled_for_gap_findings, min_score_for_gap_findings) sind hier berücksichtigt. + +### 5.1 chain_templates.yaml – “Welche Ketten gibt es, wie werden sie gematcht?” +**Zweck:** +- Definiert Templates (Muster), z.B.: + - `trigger_transformation_outcome` + - `loop_learning` + - ggf. weitere (constraint_to_adaptation usw.) + +**Template enthält typischerweise:** +- Slots (Rollen für Knoten): z.B. `trigger`, `transformation`, `outcome`, `experience`, `learning`, `behavior`, `feedback` +- Required Link Constraints (welche Slot-zu-Slot Verbindungen zwingend sind) +- Scoring/Matching-Parameter (ggf. weights, thresholds) +- Optional: template-level override für `required_links` + +**Matching-Profile (wie in Logs sichtbar):** +- z.B. Profile: `discovery`, `decisioning` +- Parameter im Profil (sichtbar in Logs): + - `required_links` (strict vs soft) + - `min_slots_filled_for_gap_findings` + - `min_score_for_gap_findings` + - ggf. `maxTemplateMatches` + +**Interpretation:** +- Templates liefern die “Soll-Struktur” +- Profile bestimmen “Wie streng” wir die Soll-Struktur im jeweiligen Workflow bewerten + +--- + +### 5.2 chain_roles.yaml – “Welche rawEdgeTypes zählen als welche Rollen?” +**Zweck:** +- Mappt `rawEdgeType` → kanonische Rollen/EdgeRoles (z.B. `causal`, `influences`, `enables_constraints`, `provenance`). +- Diese Rollen sind Grundlage für: + - `no_causal_roles` Finding + - Link-Constraint-Satisfaction (Template erwartet “causal” zwischen Slots) + - Matching Score (welche Edges zählen für welches Template) + +**Interpretation:** +- Wenn ein Edge-Typ nicht gemappt ist: + - Edge kann trotzdem im Graph auftauchen, + - aber Template/Constraint-Logik kann ihn nicht “verstehen” → führt zu Findings. + +--- + +### 5.3 analysis_policies.yaml – “Wie noisy dürfen Findings sein?” +**Zweck:** +- Zentrale Policies für Findings: + - welche Finding-Codes existieren + - Default-Severity (info/warn/error) + - Profilabhängige Overrides + - Unterdrückungsregeln (z.B. suppress in soft mode, suppress wenn confirmed, suppress wenn Score hoch…) + +**Interpretation:** +- Policies sind “produktseitige UX-Regeln”: + - Discovery: eher informativ, weniger warn + - Decisioning: klare Warnungen, wenn Qualität fehlt +- Der bereits umgesetzte Fix (`missing_link_constraints` nur in strict) ist exakt so eine Policy-Entscheidung (auch wenn technisch im Inspector gelöst). + +--- + +## 6) Ablauf des Chain Inspectors (Vorgehensweise in Mindnet) + +Hier ist ein konsistenter “Pipeline”-Ablauf, der zu den Logs passt: + +### Schritt 1: Kontext bestimmen +- Aktuelle Datei + aktuelle Section/Heading + +### Schritt 2: Edges aus aktueller Note laden +- Outgoing aus der aktuellen Section extrahieren (oder aus einem definierten Block) +- (optional/offen) Note-Level Edges ebenfalls laden und für jede Section gültig machen + +### Schritt 3: Nachbarn laden +- Backlinks (Notes, die auf die aktuelle Note verlinken) → incoming Kandidatenquellen +- Outgoing Neighbor Notes (Notes, auf die aktuelle Note verweist) → Nachbarschaft erweitern + +### Schritt 4: Edges aus Neighbor Notes laden +- Aus den verlinkenden Notes die Edges extrahieren, die auf die aktuelle Note/Section zielen +- Canonicalization: rawEdgeTypes via chain_roles.yaml in Rollen überführen + +### Schritt 5: Kandidatenfilter / Scopefilter anwenden +- Wenn `includeCandidates=false`: + - `scope: candidate` aus effective graph entfernen +- Optional weitere Filter: + - includeNoteLinks / includeSectionLinks + - direction (forward/backward/both) + - maxDepth (Traversal) + +### Schritt 6: Pfade berechnen (Paths) +- Forward/Backward (oder both) +- BFS/DFS bis `maxDepth` +- Resultat: Pfadlisten mit nodes + edges + +### Schritt 7: Template Matching +- Kandidatenknoten für Slots finden (via noteType + Nähe + Pfade) +- Links/Constraints prüfen (erwartete slot→slot Beziehungen) +- Score berechnen (z.B. per: + - Slots erfüllt + - Link constraints erfüllt + - “RoleEvidence” passend) + +### Schritt 8: Findings berechnen (Gap-Heuristics) +Beispiele: +- `missing_slot_*` wenn wichtige Slots fehlen (abhängig von Profil-Thresholds) +- `one_sided_connectivity` wenn nur incoming oder nur outgoing +- `no_causal_roles` wenn Edges da, aber keine causal Rollen im effektiven Graph +- `missing_link_constraints` nur wenn effectiveRequiredLinks=true und slotsComplete=true, requiredLinks>0, linksComplete=false + +### Schritt 9: Report ausgeben +- context, settings, neighbors, paths, findings, analysisMeta, templateMatches +- Transparenz: satisfiedLinks/requiredLinks/linksComplete bleiben sichtbar + +--- + +## 7) Strategien, die Mindnet verfolgen kann (Produkt-/UX-Strategie) + +### Strategie A: Discovery (Exploration) +**Ziel:** Möglichst schnell “wo könnte eine sinnvolle Kette entstehen?” finden. +- required_links = false (Soft Mode) +- includeCandidates = true (optional) +- findings eher informativ (info), weniger warn +- Templates mehr als Vorschläge (“plausible/weak”), nicht als harte Bewertung + +**Vorteil:** Nutzer bekommt schnell Hypothesen. +**Risiko:** Mehr Noise, mehr falsche Kandidaten – muss per Policy gedämpft werden. + +--- + +### Strategie B: Decisioning (Qualitätskontrolle) +**Ziel:** Prüfung, ob eine Kette “wirklich steht” und als belastbar gelten kann. +- required_links = true (Strict Mode) +- includeCandidates = false +- findings: warn, wenn Slots/Links fehlen +- “confirmed” nur wenn link constraints komplett + +**Vorteil:** Qualitätssicherung & Verlässlichkeit. +**Risiko:** Nutzer fühlt sich “blockiert”, wenn Graph noch im Aufbau ist. + +--- + +### Strategie C: Progressive Disclosure (hybrid) +**Ziel:** Nutzer nicht überfordern, aber zielgerichtet verbessern. +- Soft Mode für Einstieg +- Button/Toggle: “Strict prüfen” +- Candidate Edges als Vorschlag-Klasse (UI: “proposed edges”) +- Findings priorisieren: erst fehlende Slots, dann fehlende Links, dann Detail-Qualität + +--- + +## 8) Wie ein “kausaler Retriever” funktionieren könnte (Causal Retriever) + +Ein kausaler Retriever ist die Komponente, die aus dem Vault/Graphen **relevante Kausalkontexte** für den aktuellen Abschnitt liefert – idealerweise deterministisch, skalierbar und template-aware. + +### 8.1 Retrieval-Ziele +- Finde Knoten/Edges, die **kausal relevant** sind zum aktuellen Kontext: + - Ursachen (backward) + - Wirkungen/Entscheidungen (forward) + - Bedingungen/Constraints (seitlich) +- Gib nicht nur Knoten zurück, sondern: + - Pfade (explainable) + - Evidence (wo steht das) + - Role-Interpretation (warum ist das causal/influences/etc.) + +### 8.2 Retrieval-Inputs +- startNode = current section +- direction = forward/backward/both +- maxDepth +- roleFilter (optional): nur causal/influences/enables_constraints +- scopeFilter: includeCandidates, includeNoteLevel +- templateBias: bevorzugte Pfadformen (z.B. “experience→insight→decision”) + +### 8.3 Retrieval-Algorithmus (praktisch) +**Variante 1: BFS mit Rolle-Gewichtung** +- BFS über Kanten +- Priorität/Score pro Frontier: + - causal > influences > provenance + - section-scope > note-scope > candidate (wenn candidates eingeschaltet, sonst candidate=∞) +- Stop, wenn: + - maxDepth erreicht + - genug Top-N Pfade gesammelt (z.B. topNUsed) + +**Variante 2: Template-driven Retrieval** +- Wenn ein Template im Fokus ist: + - suche explizit nach Slot-Knoten (noteType matching) + - suche dann die minimalen Verbindungen, die Constraints erfüllen +- Gute Option für “Decisioning”: deterministisch prüfen. + +**Variante 3: Two-phase Retrieval** +1) Kandidaten finden (Slots) +2) Verbindungen prüfen (Constraints) +→ Liefert sehr gut “warum fehlt Link X?” Diagnosen. + +### 8.4 Output-Format +- `neighbors` (incoming/outgoing, mit evidence) +- `paths` (forward/backward, nodes+edges) +- plus “slot candidates” optional (für UI) + +--- + +## 9) Empfehlungen für robuste Tests (damit ihr nicht wieder im Kreis lauft) + +### Was ist bereits ausreichend getestet (nicht wiederholen) +- includeCandidates Filterverhalten ✅ +- missing_link_constraints Unterdrückung bei required_links=false ✅ +- strict/soft required_links via profile/template override ✅ +- “healthy graph” ergibt findings: [] ✅ +- unmapped edge type triggert Diagnose ✅ + +### Was als einziges “neues” Testziel für Abschluss 0.4.x/Start 0.5.x taugt +- **Note-level edges / note-scope**: gelten Kanten “global” pro Note oder nicht? + +**Minimal-Testdefinition (einmalig, reproduzierbar):** +1) In `02_event_trigger_detail.md` einen klaren Note-Level Block definieren (z.B. “## Note-Verbindungen”). +2) Edge dort definieren, die auf eine andere Note/Section zeigt. +3) Cursor in einer anderen Section derselben Note platzieren (z.B. “## Detail” oder “## Extra”). +4) Chain Inspector laufen lassen. +5) Erwartung: + - Edge erscheint trotzdem als outgoing/incoming + - evidence zeigt auf den Note-Level Block + - ideal: `scope: note` + +Wenn das FAIL ist → klarer 0.5.0 Task. + +--- + +## 10) Implikationen für 0.5.x / 0.6.x (wohin sinnvoll weiter) + +### 0.5.x (Stabilisierung) +- Note-level edge scope finalisieren (inkl. Report-Transparenz) +- policies (analysis_policies) als zentrale Noise-Steuerung weiter ausbauen +- Debug/Explainability weiter verbessern (effectiveRequiredLinks pro Match explizit ausgeben) + +### 0.6.x (UX & Workflows) +- Actionable Findings: “Was genau soll ich ändern?” inkl. Vorschlagtext oder Snippet +- UI-Toggles: Strict/Soft, Candidates on/off +- Template Authoring Tools: Linter, “Warum kein Match?” + +--- + +## 11) Kurzes “Was heißt das für Mindnet im Alltag?” +- Im Discovery-Modus: Mindnet ist ein **Explorationswerkzeug** (Hypothesen + Hinweise, wenig Warnungen). +- Im Decisioning-Modus: Mindnet ist ein **Qualitätsprüfer** (strict, wenige false positives). +- Der nächste große Hebel ist Note-scope: Damit wird Pflege einfacher und Ketten werden “wartbarer”. + +--- + +## 12) Appendix: Beispielhafte Report-Signale (Interpretationshilfe) + +- `findings: []` + `confidence: confirmed` + → Template passt sauber (Slots + Links vollständig im gewählten Modus). + +- `linksComplete=false` aber `required_links=false` und **kein** `missing_link_constraints` + → Soft Mode: bewusst kein “Warn-Noise”, aber Transparenz bleibt. + +- `no_causal_roles` + → Edges existieren, aber keine davon wird als “causal” interpretiert (Mapping oder rawEdgeType Problem). + +- `edgesUnmapped > 0` + → chain_roles unvollständig oder Edge-Typ ist neu/fehlerhaft geschrieben. + +- `effectiveIncoming=0` bei includeCandidates=false, aber incoming candidate-edge existiert + → Filter funktioniert wie geplant. + +--- + +ENDE