mindnet_obsidian/docs/02_concepts/03_chain_identification_and_matching.md
Lars a9b3e2f0e2
Some checks are pending
Node.js build / build (20.x) (push) Waiting to run
Node.js build / build (22.x) (push) Waiting to run
Implement Chain Workbench and Vault Triage features in Mindnet plugin
- Introduced new workflows for Chain Workbench and Vault Triage, enhancing user capabilities for managing template matches and identifying chain gaps.
- Added commands for opening the Chain Workbench and scanning the vault for chain gaps, improving the overall functionality of the plugin.
- Updated documentation to include detailed instructions for the new workflows, ensuring users can effectively utilize the features.
- Enhanced the UI for both the Chain Workbench and Vault Triage Scan, providing a more intuitive user experience.
- Implemented tests for the new functionalities to ensure reliability and accuracy in various scenarios.
2026-01-26 10:51:12 +01:00

11 KiB
Raw Permalink Blame History

Chain-Identifikation und Template Matching

Übersicht

Das System identifiziert und füllt Chains durch einen mehrstufigen Prozess:

  1. Graph-Indexierung: Erfassung aller Edges (Kanten) im lokalen Subgraph
  2. Candidate-Node-Sammlung: Identifikation potenzieller Knoten für Template-Slots
  3. Template Matching: Backtracking-Algorithmus zur optimalen Slot-Zuordnung
  4. Link-Validierung: Prüfung, ob Edges zwischen zugewiesenen Slots existieren
  5. Scoring & Confidence: Bewertung der Match-Qualität

1. Graph-Indexierung

Edge-Erfassung

Der Chain Inspector (src/analysis/chainInspector.ts) erfasst alle Edges im lokalen Subgraph:

  • Current Section: Die aktuelle Section (file + heading)
  • Incoming Edges: Edges, die zur aktuellen Section zeigen
  • Outgoing Edges: Edges, die von der aktuellen Section ausgehen
  • Neighbor Notes: Verbundene Notes werden geladen, um den Subgraph zu erweitern

Edge-Scopes

Edges können drei Scopes haben:

  • section: Section-spezifisch ([[Note#Heading]])
  • note: Note-weit ([[Note]] ohne Heading)
  • candidate: In "## Kandidaten" Zone

Filterung

Edges werden basierend auf InspectorOptions gefiltert:

  • includeNoteLinks: Ob Note-Scope Edges einbezogen werden
  • includeCandidates: Ob Candidate Edges einbezogen werden
  • maxDepth: Maximale Tiefe für Path-Traversal

2. Candidate-Node-Sammlung

Prozess (buildCandidateNodes)

Für jeden Edge im Subgraph werden Candidate Nodes erstellt:

  1. Source Nodes: Alle Knoten, von denen Edges ausgehen
  2. Target Nodes: Alle Knoten, zu denen Edges zeigen
  3. Note-Type-Extraktion: Frontmatter type: wird aus jeder Note extrahiert
  4. Deduplizierung: Gleiche Knoten (file + heading) werden nur einmal erfasst

Node-Repräsentation

interface CandidateNode {
  nodeKey: {
    file: string;
    heading: string | null;
  };
  noteType: string; // z.B. "insight", "decision", "experience"
}

Maximale Anzahl

Standardmäßig werden maximal 30 Candidate Nodes gesammelt (konfigurierbar).


3. Template Matching

Template-Definition (chain_templates.yaml)

Jedes Template definiert:

  • Slots: Positionen in der Chain mit erlaubten Note-Types
  • Links: Erwartete Verbindungen zwischen Slots mit erlaubten Edge-Roles

Beispiel: loop_learning

slots:
  - id: experience
    allowed_node_types: [experience, journal, event]
  - id: learning
    allowed_node_types: [insight, principle, value, belief, skill, trait]
  - id: behavior
    allowed_node_types: [habit, decision, task]
  - id: feedback
    allowed_node_types: [experience, journal, event, state]

links:
  - from: experience
    to: learning
    allowed_edge_roles: [causal, provenance, influences]
  - from: learning
    to: behavior
    allowed_edge_roles: [influences, enables_constraints, causal]
  - from: behavior
    to: feedback
    allowed_edge_roles: [causal, influences]

Backtracking-Algorithmus (findBestAssignment)

Der Algorithmus findet die beste Slot-Zuordnung durch systematisches Ausprobieren:

  1. Slot-Filterung: Für jeden Slot werden nur Candidate Nodes gefiltert, die den allowed_node_types entsprechen
  2. Backtracking: Rekursives Durchprobieren aller möglichen Zuordnungen
  3. Distinct Nodes: Jeder Knoten kann nur einmal zugeordnet werden (wenn distinct_nodes: true)
  4. Scoring: Jede vollständige Zuordnung wird bewertet
  5. Best Match: Die Zuordnung mit dem höchsten Score wird zurückgegeben

Slot-Zuordnung

function backtrack(assignment: Map<string, CandidateNode>, slotIndex: number) {
  // Wenn alle Slots zugeordnet sind:
  if (slotIndex >= slots.length) {
    const result = scoreAssignment(...); // Bewerte Zuordnung
    if (result.score > bestScore) {
      bestMatch = result; // Speichere besten Match
    }
    return;
  }
  
  // Probiere jeden passenden Candidate für diesen Slot
  for (const candidate of slotCandidates.get(slot.id)) {
    if (!alreadyAssigned(candidate)) {
      assignment.set(slot.id, candidate);
      backtrack(assignment, slotIndex + 1); // Rekursiv weiter
      assignment.delete(slot.id); // Backtrack
    }
  }
  
  // Auch: Slot leer lassen (für unvollständige Chains)
  backtrack(assignment, slotIndex + 1);
}

Edge-Suche (findEdgeBetween)

Für jedes Template-Link wird geprüft, ob ein Edge zwischen den zugewiesenen Slots existiert:

  1. Node-Keys: fromKey = "file:heading", toKey = "file:heading"
  2. Edge-Suche: Durchsuche allEdges nach passendem Edge
  3. Canonicalisierung: Edge-Typ wird auf Canonical gemappt (via edge_vocabulary.md)
  4. Role-Mapping: Canonical Edge-Typ wird auf Role gemappt (via chain_roles.yaml)
  5. Role-Validierung: Prüfe, ob Edge-Role in allowed_edge_roles enthalten ist

Role-Evidence

Wenn ein Link erfüllt ist, wird Role Evidence gespeichert:

roleEvidence.push({
  from: "learning",        // Slot-ID (nicht Dateipfad!)
  to: "behavior",          // Slot-ID
  edgeRole: "causal",      // Role aus chain_roles.yaml
  rawEdgeType: "resulted_in" // Original Edge-Typ im Vault
});

Wichtig: roleEvidence verwendet Slot-IDs, nicht Dateipfade!


5. Scoring & Confidence

Scoring (scoreAssignment)

Slot-Scoring:

  • Jeder zugewiesene Slot: +2 Punkte

Link-Scoring:

  • Erfüllter Link (mit erlaubter Role): +10 Punkte
  • Fehlender Link (wenn required_links: true): -5 Punkte
  • Falsche Role (wenn required_links: true): -5 Punkte

Confidence-Berechnung

Die Confidence wird nach dem Matching berechnet:

  1. weak: Wenn slotsComplete === false (fehlende Slots)
  2. confirmed: Wenn slotsComplete === true UND linksComplete === true UND mindestens eine causal-ish Role Evidence
  3. plausible: Sonst (Slots vollständig, aber Links unvollständig oder keine causal Roles)

Causal-ish Roles: ["causal", "influences", "enables_constraints"] (konfigurierbar in chain_templates.yaml)

Completeness

  • slotsComplete: missingSlots.length === 0
  • linksComplete: satisfiedLinks === requiredLinks

6. Template-Matching-Profile

Profile-Definition

Profile steuern die Matching-Strenge:

discovery (schreibfreundlich):

required_links: false  # Links sind optional
min_slots_filled_for_gap_findings: 2
min_score_for_gap_findings: 8

decisioning (strikt):

required_links: true  # Links sind Pflicht
min_slots_filled_for_gap_findings: 3
min_score_for_gap_findings: 18

Profile-Auflösung

  1. Settings: Plugin-Einstellung templateMatchingProfile
  2. Template: Template-spezifische matching.required_links
  3. Defaults: defaults.matching.required_links

7. Beispiel: Loop Learning Match

Input

  • Current Section: Tests/03_insight_transformation.md#Kern
  • Edges im Subgraph: 8 Edges (1 current, 7 neighbors)
  • Candidate Nodes: 4 Nodes (experience, learning, behavior, feedback)

Template

name: loop_learning
slots: [experience, learning, behavior, feedback]
links:
  - experience → learning
  - learning → behavior
  - behavior → feedback

Matching-Prozess

  1. Slot-Zuordnung (Backtracking):

    • experienceTests/02_event_trigger_detail.md#Detail (noteType: event)
    • learningTests/03_insight_transformation.md#Kern (noteType: insight)
    • behaviorTests/04_decision_outcome.md#Entscheidung (noteType: decision)
    • feedbackTests/01_experience_trigger.md#Kontext (noteType: experience)
  2. Link-Validierung:

    • experience → learning: Kein Edge gefunden
    • learning → behavior: Edge resulted_in mit Role causal gefunden
    • behavior → feedback: Kein Edge gefunden
  3. Scoring:

    • Slots: 4 × 2 = 8 Punkte
    • Links: 1 × 10 = 10 Punkte
    • Gesamt: 18 Punkte
  4. Resultat:

    {
      "templateName": "loop_learning",
      "score": 18,
      "slotsComplete": true,
      "linksComplete": false,
      "satisfiedLinks": 1,
      "requiredLinks": 3,
      "confidence": "plausible",
      "roleEvidence": [
        {
          "from": "learning",
          "to": "behavior",
          "edgeRole": "causal",
          "rawEdgeType": "resulted_in"
        }
      ]
    }
    

8. Wichtige Konzepte

Slot-IDs vs. Dateipfade

  • Slot-IDs: Template-interne Bezeichner ("learning", "behavior")
  • Dateipfade: Vault-Pfade ("Tests/03_insight_transformation.md")
  • roleEvidence verwendet Slot-IDs, nicht Dateipfade!

Canonicalisierung

  • Intern: Edge-Typen werden auf Canonical gemappt (für Analyse)
  • Vault: Original Edge-Typen (Aliase) bleiben unverändert
  • Schreiben: Plugin schreibt keine Canonicals, nur User-gewählte Typen

Distinct Nodes

Wenn distinct_nodes: true:

  • Jeder Knoten kann nur einmal pro Template zugeordnet werden
  • Verhindert zirkuläre Zuordnungen

Edge-Target-Resolution

Edges können verschiedene Pfad-Formate verwenden:

  • Vollständig: Tests/03_insight_transformation.md
  • Basename: 03_insight_transformation
  • Wikilink: [[03_insight_transformation]]

Das System normalisiert alle Formate für konsistente Matching.


9. Integration mit Chain Workbench

Der Chain Workbench nutzt die Template Matches, um:

  1. Todos zu generieren:

    • missing_slot: Fehlende Slot-Zuordnungen
    • missing_link: Fehlende Links zwischen Slots
    • weak_roles: Links mit schwachen (nicht-causalen) Roles
  2. Status zu berechnen:

    • complete: Slots + Links vollständig
    • near_complete: 1-2 Links fehlen oder 1 Slot fehlt
    • partial: Mehrere Lücken
    • weak: Nur structural/temporal Roles, keine causal Roles
  3. Actions anzubieten:

    • insert_edge_forward: Edge einfügen (von Slot A nach Slot B)
    • link_existing: Bestehenden Knoten verlinken
    • create_note_via_interview: Neue Note für Slot erstellen

10. Konfigurationsdateien

chain_templates.yaml

Definiert Template-Strukturen:

  • Slots mit erlaubten Note-Types
  • Links mit erlaubten Edge-Roles
  • Profile (discovery, decisioning)

chain_roles.yaml

Mappt Edge-Typen auf Roles:

  • causal: Direkte Kausalität
  • influences: Indirekte Einflussnahme
  • enables_constraints: Ermöglicht/Einschränkt
  • structural: Strukturelle Beziehung
  • temporal: Zeitliche Beziehung

edge_vocabulary.md

Definiert Canonical Edge-Typen und Aliase:

  • Canonical: resulted_in
  • Aliase: führt_zu, resultiert_in, etc.

graph_schema.md

Definiert Note-Type-Kompatibilität:

  • Welche Edge-Typen sind typisch für insight → decision?
  • Welche Edge-Typen sind verboten?

Zusammenfassung

Das System identifiziert Chains durch:

  1. Graph-Indexierung: Erfassung aller Edges im lokalen Subgraph
  2. Candidate-Sammlung: Identifikation potenzieller Knoten
  3. Backtracking-Matching: Optimale Slot-Zuordnung
  4. Link-Validierung: Prüfung vorhandener Edges
  5. Scoring: Bewertung der Match-Qualität

Das Ergebnis sind Template Matches mit:

  • Slot-Zuordnungen (welche Knoten in welchen Slots)
  • Link-Status (welche Links erfüllt/fehlend)
  • Confidence (confirmed/plausible/weak)
  • Role Evidence (welche Edges welche Roles haben)

Diese Matches werden dann im Chain Workbench verwendet, um konkrete Todos und Actions zu generieren.