mindnet_obsidian/docs/DANGLING_TARGET_CASES.md
Lars 90ccec5f7d
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 findings fixing and template matching features in Mindnet plugin
- Added a new command to fix findings in the current section of a markdown file, enhancing user experience by automating issue resolution.
- Introduced settings for configuring actions related to missing notes and headings, allowing for customizable behavior during the fixing process.
- Enhanced the chain inspector to support template matching, providing users with insights into template utilization and potential gaps in their content.
- Updated the analysis report to include detailed metadata about edges and role matches, improving the clarity and usefulness of inspection results.
- Improved error handling and user notifications for fixing findings and template matching processes, ensuring better feedback during execution.
2026-01-18 21:10:33 +01:00

5.5 KiB

Dangling Target Cases - Übersicht

Welche Fälle werden erkannt?

Chain Inspector v0.2+ erkennt zwei Arten von dangling_target Findings:

1. dangling_target (Severity: ERROR)

Wann wird es erkannt?

  • Ein outgoing Edge von der aktuellen Section verweist auf eine Datei, die nicht existiert
  • Die Datei wird über app.metadataCache.getFirstLinkpathDest() aufgelöst
  • Wenn die Auflösung null zurückgibt → dangling_target Finding

Welche Edges werden geprüft?

  • Alle section-scoped Edges aus der aktuellen Section (nicht Note-scoped, nicht Candidates)
  • Edges aus expliziten Edge-Callouts: > [!edge] <type>\n> [[TargetFile]]
  • Edges aus Semantic Mapping Blocks

Beispiele:

## Meine Section

> [!edge] causes
> [[MissingNote]]  ← dangling_target (ERROR)

> [!abstract] 🕸️ Semantic Mapping
>> [!edge] influences
>> [[AnotherMissingNote]]  ← dangling_target (ERROR)

Was wird NICHT geprüft?

  • Note-scoped Edges (aus "## Note-Verbindungen" Zone)
  • Candidate Edges (aus "## Kandidaten" Zone)
  • Incoming Edges (nur outgoing Edges werden geprüft)

2. dangling_target_heading (Severity: WARN)

Wann wird es erkannt?

  • Ein outgoing Edge verweist auf eine existierende Datei, aber mit einem Heading, das nicht existiert
  • Die Datei existiert (wird erfolgreich aufgelöst)
  • Das Heading wird in metadataCache.getFileCache() geprüft
  • Wenn das Heading nicht in der Liste der Headings gefunden wird → dangling_target_heading Finding

Beispiele:

## Meine Section

> [!edge] references
> [[ExistingNote#MissingHeading]]  ← dangling_target_heading (WARN)

> [!edge] part_of
> [[AnotherNote#NonExistentSection]]  ← dangling_target_heading (WARN)

Was passiert wenn File Cache nicht verfügbar ist?

  • Wenn getFileCache() null zurückgibt (z.B. Datei noch nicht indexiert)
  • Kein Finding (wird übersprungen, da Cache später aktualisiert wird)

Welche Fälle sind behebbar?

Behebbar via Fix Actions:

  1. dangling_target (ERROR)

    • Action 1: Create Missing Note
      • Erstellt neue Note (skeleton oder mit Profile/Wizard)
      • Verwendet Settings: fixActions.createMissingNote.*
    • Action 2: Retarget Link
      • Zeigt Entity Picker Modal
      • Ersetzt Link im Editor zu existierender Note
      • Behält Heading bei wenn vorhanden
  2. dangling_target_heading (WARN)

    • Action 1: Create Missing Heading
      • Erstellt Heading am Ende der Target-Datei
      • Verwendet Settings: fixActions.createMissingHeading.level
    • Action 2: Retarget to Existing Heading
      • Zeigt Heading-Picker (aus File Cache)
      • Ersetzt Link im Editor zu existierendem Heading
  3. only_candidates (INFO)

    • Action: Promote Candidate Edge
      • Befördert Candidate-Edge zu explizitem Edge
      • Fügt Edge zu aktueller Section hinzu
      • Verwendet Settings: fixActions.promoteCandidate.keepOriginal

NICHT behebbar (keine Fix Actions):

  • missing_edges - Section hat keine Edges (nur Info)
  • one_sided_connectivity - Nur incoming ODER nur outgoing Edges (nur Info)
  • no_causal_roles - Keine causal-ish Rollen (nur Info)

Technische Details

Edge-Filterung für dangling_target Check

// sectionEdges = alle Edges aus aktueller Section
const sectionEdges = currentEdges.filter((edge) => {
  // Nur section-scoped Edges (nicht note-scoped, nicht candidates)
  if (edge.scope === "candidate") return false;
  if (edge.scope === "note") return false;
  
  // Nur Edges aus aktueller Section
  return "sectionHeading" in edge.source
    ? edge.source.sectionHeading === context.heading &&
      edge.source.file === context.file
    : false;
});

Datei-Auflösung

const resolvedFile = app.metadataCache.getFirstLinkpathDest(
  normalizeLinkTarget(targetFile),
  context.file
);

if (!resolvedFile) {
  // → dangling_target (ERROR)
}

Heading-Check

if (targetHeading !== null) {
  const targetContent = app.metadataCache.getFileCache(resolvedFile);
  if (targetContent) {
    const headings = targetContent.headings || [];
    const headingExists = headings.some(
      (h) => h.heading === targetHeading
    );
    
    if (!headingExists) {
      // → dangling_target_heading (WARN)
    }
  }
}

Bekannte Einschränkungen

  1. Trash Detection: Dateien im .trash Ordner werden als "nicht existierend" erkannt (korrektes Verhalten)

  2. File Cache: Wenn getFileCache() nicht verfügbar ist, wird Heading-Check übersprungen (akzeptabel, da Cache später aktualisiert wird)

  3. Case Sensitivity: Heading-Matching ist case-sensitive (abhängig von Obsidian-Konfiguration)

  4. Note-scoped Edges: Werden nicht auf dangling_target geprüft (nur section-scoped Edges)

  5. Candidate Edges: Werden nicht auf dangling_target geprüft (nur explizite Edges)

Zusammenfassung

Finding Severity Geprüft für Behebbar Actions
dangling_target ERROR Outgoing section-scoped Edges Create Note, Retarget Link
dangling_target_heading WARN Outgoing section-scoped Edges mit Heading Create Heading, Retarget to Heading
only_candidates INFO Sections mit nur Candidate-Edges Promote Candidate
missing_edges INFO Sections ohne Edges -
one_sided_connectivity INFO Sections mit nur incoming/outgoing -
no_causal_roles INFO Sections ohne causal roles -