---
type: skill
agent_ready: true
schema_version: 1
bundle_version: "0.28.0"
name: vault-gap-analysis
description: "Analysiert den Vault als Wissensgraph, identifiziert schwach verbundene Themencluster, bewertet Lücken inhaltlich und schlägt konkrete Brücken vor. Einsetzen wenn Wissenslücken im Vault gefunden, der Graph nach einer Wachstumsphase geprüft oder bewusst Brücken zwischen isolierten Themen geschlagen werden sollen."
tags:
  - skill
  - second-brain
  - karpathy
  - graph-analysis
  - vault-maintenance
scope: vault
bundle_skill: true
default_active:
  allgemein: false
  karpathy: true
depends_on: []
conflicts_with: []
created: 2026-05-16
updated: 2026-05-16
---

# vault-gap-analysis

Immer eine Lücke auf einmal: der Skill zeigt maximal fünf Lücken, geht sie einzeln durch und wartet auf eine explizite Antwort, bevor er zur nächsten springt. Die History in `gap-history.json` stellt sicher, dass bereits gesichtete oder ignorierte Lücken nicht bei jedem Lauf neu auftauchen.

## Arbeitsteilung: Python vs. Claude

| Aufgabe | Ausführer |
|---|---|
| Vault parsen, Graph bauen, Cluster erkennen, Lücken-Scores berechnen | `graph_analyzer.py` (deterministisch) |
| Lücken inhaltlich bewerten, Brücken formulieren, History pflegen | Claude |

## Aufruf

```bash
PYTHONUTF8=1 python .skills/vault-gap-analysis/graph_analyzer.py --vault <vault-root>
```

Optional:

```bash
python .skills/vault-gap-analysis/graph_analyzer.py --vault <vault> --output <pfad> --dry-run --config <config.yaml>
```

Der Output-Pfad wird aus `paths.report_file` in `skill.config.yaml` aufgelöst. Default: `{system}/Vault Gap Analysis/gap-report.md`.

## Abhängigkeiten (pyproject.toml)

`networkx>=3.0,<4.0` und `python-louvain>=0.16,<1.0` (Import-Name `community`) müssen als Bundle-Deps eingetragen sein. `pyyaml` ist bereits im Bundle enthalten.

## Feature-Flags

Konfigurierbar in `skill.config.yaml` unter `features:`. Diese Flags werden beim Aufruf aus der Config geladen:

| Flag | Typ | Default | Beschreibung |
|---|---|---|---|
| `min_cluster_size` | int | `3` | Cluster unter dieser Größe werden ignoriert |
| `max_gaps` | int | `10` | Maximale Lücken im Report |
| `max_oneway_links` | int | `15` | Maximale einseitige Links im Report |
| `semantic_boost_max` | float | `0.15` | Maximaler semantischer Boost auf Gap-Score |
| `louvain_random_seed` | int | `42` | Seed für deterministisches Louvain-Clustering |

## Scope-Konfiguration

Die `scope`-Sektion in `skill.config.yaml` steuert, welche Dateien und Verzeichnisse analysiert werden:

- `scope.exclude_dirs` — Verzeichnisse komplett ausschließen (z.B. `.obsidian`, `.claude`)
- `scope.exclude_paths` — Pfade relativ zum Vault ausschließen (z.B. `{logbuch}/Z Session Logs`)
- `scope.exclude_files` — Einzelne Dateinamen ausschließen (z.B. `gap-report.md`)

## Stufe 2: Claude-Bewertung und Aktionen

Nach dem Python-Lauf führt Claude diese Schritte aus:

### Schritt 1 — Report und History laden

1. `{system}/Vault Gap Analysis/gap-report.md` lesen (Pfad aus `paths.report_file`)
2. `gap-history.json` im Skill-Verzeichnis lesen (falls vorhanden)

### Schritt 2 — Delta-Filter

Jede Lücke im Report wird über ihr **Label-Paar** identifiziert. Cluster-IDs ändern sich bei jedem Lauf, Labels sind stabil.

Filterregeln:
- Lücken mit Status `ignoriert` oder `erledigt` in der History: **überspringen**
- Lücken mit Status `gesichtet`: **nur zeigen, wenn sich der Score um mehr als 0.1 verändert hat**
- Neue Lücken (nicht in History): **aufnehmen**
- **Maximal 5 Lücken** an den Nutzer präsentieren

### Schritt 3 — Inhaltliche Bewertung

Für jede verbleibende Lücke:

1. **Relevanz prüfen:** Beide Cluster-Descriptions und die Tag-Überschneidung lesen. Macht eine Verbindung inhaltlich Sinn? Wenn nein: als `ignoriert` in die History schreiben.
2. **Brückenfrage formulieren:** Eine konkrete, verständliche Frage, die beide Cluster verbindet. Keine Graph-Theorie, keine Informatik-Fachbegriffe.
3. **Beispielaktionen** (2–3 pro Lücke): Konkrete nächste Schritte.

   Mögliche Aktionstypen:
   - **Wikilink setzen:** In [[Datei A]] einen Link auf [[Datei B]] setzen
   - **Neue Notiz:** Eine kurze Notiz schreiben, die Thema X mit Thema Y verbindet
   - **Bestehende Notiz erweitern**
   - **Recherche-Idee**
   - **Content-Idee:** Das wäre ein guter Beitrags-Aufhänger

### Schritt 4 — Ergebnis präsentieren (Einzelmodus)

**WICHTIG: Immer nur EINE Lücke auf einmal zeigen.** Der Nutzer wird Schritt für Schritt geführt.

Ablauf:
1. Kurze Übersicht: "Ich habe X relevante Lücken gefunden. Wir gehen sie einzeln durch."
2. Erste Lücke zeigen:

```
### Lücke 1 von X: [Kurztitel]

**Worum geht es:** [2–3 Sätze, welche Wissensbereiche nicht verbunden sind]

**Brückenfrage:** [Eine konkrete Frage, die beide Bereiche verbindet]

**Hintergrund:** [3–5 Sätze Kontext]

**Mein Vorschlag:** [Die eine konkreteste Aktion]

Soll ich das umsetzen? (ja / nein / ignorieren / überspringen)
```

3. Auf Antwort warten:
   - **„ja"** → Aktion ausführen, dann nächste Lücke
   - **„nein"** → Als `gesichtet` markieren, nächste Lücke
   - **„ignorieren"** → Als `ignoriert` markieren (kommt nicht wieder)
   - **„überspringen"** → Nächste Lücke ohne Statusänderung

### Schritt 5 — Aktionen ausführen

**„Schließ die Brücke"** (z.B. „Schließ die Brücke bei 1" oder „Mach 1"):

1. Die betroffenen Dateien lesen
2. `## Verknüpfungen` prüfen:
   - Falls vorhanden: Wikilink ans Ende des Abschnitts anfügen
   - Falls nicht: `## Verknüpfungen` als letzten Abschnitt anlegen
3. `updated`-Feld im Frontmatter auf heute setzen
4. Lücke in `gap-history.json` als `erledigt` markieren

**„Ignorieren"** → In `gap-history.json` als `ignoriert` markieren

**„Gesichtet"** → In `gap-history.json` als `gesichtet` markieren

### Schritt 6 — Einseitige Links prüfen

Der Report enthält einen Abschnitt „Einseitige Links (Rücklink fehlt)". Claude prüft diese Liste und schlägt sinnvolle Rücklinks vor. Nicht jeder einseitige Link braucht einen Rücklink.

Format:
```
**Einseitige Links:** X gefunden. Davon sehen Y nach sinnvollen Rücklinks aus:
- [[Datei B]] könnte auf [[Datei A]] zurücklinken, weil...

Soll ich die Rücklinks setzen? (ja / nein / einzeln durchgehen)
```

## gap-history.json Format

```json
{
  "lücken": {
    "bereich-a, thema-x | bereich-b, thema-y": {
      "status": "neu",
      "score": 1.0,
      "erstmals_gesehen": "2026-01-01",
      "zuletzt_aktualisiert": "2026-01-01",
      "aktion": null
    }
  },
  "meta": {
    "letzter_lauf": "2026-01-01",
    "version": 1
  }
}
```

**Status-Werte:** `neu` | `gesichtet` | `ignoriert` | `erledigt`

**Label-Paar-Schlüssel:** Beide Cluster-Labels alphabetisch sortiert, getrennt durch ` | `.

## Eval-Set

Eingefrorene Assertions unter `.skills/vault-gap-analysis/eval/vault-gap-analysis.eval.json`. Runner: `run_evals.py`. Pass-Rate muss 100 Prozent sein.

## Verknüpfungen

- [[INDEX|INDEX.md]]
- [[AGENTS|AGENTS.md]]
