---
type: skill
agent_ready: true
schema_version: 1
bundle_version: "0.28.0"
name: index-rebuild
description: "Regeneriert eine flache INDEX.md im Vault-Root aus dem aktuellen Vault-Stand. Karpathy-Compiler-Pattern raw -> wiki -> index -> runtime. Alle Pfade kommen aus skill.config.yaml plus bundle.json.vault_layout."
tags:
  - skill
  - index-rebuild
  - karpathy
scope: vault
bundle_skill: true
default_active:
  allgemein: true
depends_on: []
conflicts_with: []
created: 2026-05-12
updated: 2026-05-13
---

# index-rebuild

Der Rebuild ist idempotent und deterministisch: gleicher Vault-Stand ergibt gleiche INDEX.md. Das Skript liest Frontmatter, filtert archivierte Projekte automatisch aus und hält das `created`-Datum sticky. Wann ein Rebuild sinnvoll ist und was er genau prüft, steht im Abschnitt „Wann einsetzen" und im Eval-Set unten.

## Wann einsetzen

- Wenn der User „Index neu bauen", „INDEX.md aktualisieren", „Vault-Index rebuilden", „rebuild index" oder Ähnliches sagt.
- Automatisch nach jedem erfolgreichen Curator-Lauf (sobald neue Wiki-Einträge entstehen).
- Manuell vor jedem Weekly Review.
- Nach größeren Umstrukturierungen im Vault (neuer Projektordner, neue Ressourcenkategorie, Archivierung eines Projekts).

## Ablauf

1. **Skript ausführen** im Vault-Root:
   ```bash
   PYTHONUTF8=1 python .skills/index-rebuild/build_index.py --diff
   ```
   Zeigt den Unified-Diff gegen die bestehende `INDEX.md` auf stdout. Noch kein Schreiben.
2. **Diff prüfen** und dem User vorlegen. Bei Bestätigung:
   ```bash
   PYTHONUTF8=1 python .skills/index-rebuild/build_index.py
   ```
   Das schreibt `INDEX.md` überschreibend.
3. **Evals laufen lassen:**
   ```bash
   PYTHONUTF8=1 python .skills/index-rebuild/run_evals.py --verbose
   ```
   Muss 100 Prozent Pass-Rate liefern. Bei rot sofort stoppen und melden.
4. **Ergebnis melden.** Drei Sätze: wie viele Einträge insgesamt, was sich geändert hat, ob die Evals grün waren.

## Regeln (Autonomy-Level 1)

- **Kein Schreiben ohne Diff-Vorlage.** Der Skill steht auf Autonomy-Level 1: Diff vorlegen, Bestätigung abwarten, dann schreiben.
- **Frontmatter-`updated`** wird auf das heutige Datum gesetzt. `created` wird sticky übernommen (siehe unten).
- **Sektionsreihenfolge** ist verbindlich: Kontext, Projekte (aktiv), Bereiche, Ressourcen, Routinen, Skills, Commands, Letzte Änderungen. Wird vom Eval geprüft.
- **Archivierte Projekte** (Frontmatter `status: archiviert`) werden automatisch ausgefiltert.
- **Wenn `INDEX.md` identisch bleibt**, gibt das Skript „INDEX.md unchanged" aus und schreibt nicht.

## Sticky-Created-Date

Das `created`-Feld im INDEX.md-Frontmatter wird beim ersten Lauf auf das heutige Datum gesetzt. Bei jedem weiteren Lauf liest `build_index.py` die bestehende `INDEX.md`, extrahiert den `created`-Wert per Regex und übernimmt ihn unverändert. Das Datum wandert also nicht, egal wie oft der Index neu gebaut wird.

## Pfade und Konfiguration

Alle Pfade kommen aus `skill.config.yaml` (optional) plus `bundle.json.vault_layout`. Fehlt die Config-Datei, greifen die Defaults des Loaders.

Konfigurierbare Felder:

| Feld | Default | Bedeutung |
|---|---|---|
| `paths.output_file` | `INDEX.md` | Ausgabedatei (relativ zu Vault-Root) |
| `paths.routinen_subdir` | `{resources}/Routinen` | Unterordner für die Routinen-Sektion |
| `paths.skills_dir` | `.claude/skills` | Skills-Verzeichnis |
| `paths.commands_dir` | `.claude/commands` | Commands-Verzeichnis |
| `paths.evals_file` | `.skills/index-rebuild/eval/index-rebuild.eval.json` | Eingefrorene Eval-Liste |
| `features.section_headings` | 8 Sektionen (siehe unten) | Sektion-Headings in verbindlicher Reihenfolge |
| `features.resource_skip_subdirs` | `["00_Images", "00_Sources", "Routinen"]` | Unterordner in `{resources}`, die übersprungen werden |
| `features.recent_changes_extra_skip` | `[]` | Zusätzliche Skip-Pfade für „Letzte Änderungen" |
| `features.recent_changes_limit` | `10` | Max. Einträge in „Letzte Änderungen" |
| `features.max_description_len` | `140` | Max. Beschreibungslänge in Zeichen |
| `features.total_size_max` | `20000` | Hard-Limit für INDEX.md-Größe (Byte) |
| `features.footer_links` | `[]` | Wikilinks im `## Verknüpfungen`-Block |
| `features.body_intro` | (generischer Text) | Einleitungstext unter H1 |
| `frontmatter.type` | `index` | type-Feld im Frontmatter |
| `frontmatter.tags` | `[index, runtime]` | Tags im Frontmatter |
| `frontmatter.description` | (generisch) | description-Feld im Frontmatter |

### Sektion-Headings (Default)

```yaml
section_headings:
  - "## Kontext"
  - "## Projekte (aktiv)"
  - "## Bereiche"
  - "## Ressourcen"
  - "## Routinen"
  - "## Skills"
  - "## Commands"
  - "## Letzte Änderungen"
```

### Footer-Links

Wenn `footer_links` leer ist (Default), wird kein `## Verknüpfungen`-Block geschrieben. Mit mindestens einem Eintrag erscheint der Block mit allen konfigurierten Wikilinks.

## Karpathy-Compiler-Kette

Der Index ist die dritte Schicht in Karpathys Compiler-Analogie:

```
raw (Markdown-Dateien im Vault)
  → wiki (strukturierte Notizen in Ordnern 00–08)
    → index (diese INDEX.md, flacher Überblick)
      → runtime (Claude liest INDEX.md beim Session-Start)
```

Kein Vektor-Store, kein Embedding, kein RAG. Der Index funktioniert als Token-sparender Startpunkt: eine Datei lesen statt den ganzen Vault.

## Locale

Default: `de`. Der Skill schreibt keine Slug-basierten Dateinamen und braucht keine Locale-Daten für Stopwords. Der `locale`-Schlüssel in der Config hat keinen Effekt auf die Index-Ausgabe, aber er kann für zukünftige Erweiterungen gesetzt werden.

## Eval-Set

15 eingefrorene Assertions unter `.skills/index-rebuild/eval/index-rebuild.eval.json`. Der Runner ist `run_evals.py` im Skill-Ordner. Pass-Rate muss 100 Prozent sein.

Assertion-Überblick:

| ID | Prüft |
|---|---|
| `sections_order` | Sektionen in verbindlicher Reihenfolge |
| `frontmatter_updated` | `updated` ist heutiges Datum |
| `frontmatter_type` | `type: index` |
| `all_active_projects` | Alle aktiven Projekte im Index |
| `no_archived_projects` | Archivierte Projekte ausgelassen |
| `wikilinks_valid` | Keine toten Wikilinks |
| `description_length` | Keine zu langen Descriptions |
| `total_size` | INDEX.md unter `total_size_max` |
| `no_duplicates` | Keine doppelten Wikilinks im Body |
| `kontext_has_all_files` | Alle `{context}`-Dateien im Index |
| `skills_has_all` | Alle Skills mit SKILL.md im Index |
| `verknuepfungen_block` | Footer-Block matcht `footer_links` |
| `recent_changes_limit` | Höchstens `recent_changes_limit` Einträge |
| `frontmatter_created_sticky` | `created` bleibt bei wiederholtem Lauf konstant |
| `footer_block_optional` | Footer-Block fehlt bei leerer `footer_links` |

Hinweis zum Vault-Drift: Im Quell-Vault lag die Eval-Liste unter einem Bereich-Ordner. Das Bundle nutzt `.skills/index-rebuild/eval/index-rebuild.eval.json` — der Vault-Pfad ist nicht mehr relevant.

## Optionen des Skripts

- `--dry-run`: Gibt den neuen Index auf stdout, schreibt nichts.
- `--diff`: Gibt Unified-Diff gegen die bestehende Datei, schreibt nichts.
- `--vault PATH`: Überschreibt den Vault-Pfad. Standard: current working directory.

## Abgrenzung

Dieser Skill liest ausschließlich Vault-Dateien und schreibt ausschließlich in `paths.output_file` (Default: `INDEX.md`).

Er fasst niemals an:
- Projektordner oder -steckbriefe
- Daily Notes, Session Logs oder andere Logbuch-Dateien
- Skill-Dateien oder andere `.claude/`-Inhalte (nur gelesen, nicht geschrieben)
- Dateien in `{archive}` oder `{attachments}` (komplett übersprungen)

Er führt niemals aus:
- Löschungen jeglicher Art
- Schreiboperationen außerhalb von `paths.output_file`

## Verknüpfungen

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