---
type: skill
agent_ready: true
schema_version: 1
bundle_version: "0.28.0"
name: migration
description: "Strukturiertes Migrations-Skill für die Übernahme von Inhalten aus einem bestehenden Vault in das frisch installierte Agentic Second Brain. Read-only-Scan des alten Vaults mit harter Pfad-Whitelist, AI-Review pro Datei, einzelne User-Bestätigung pro Eintrag. `default_active.allgemein: false` — Aktivierung erfolgt opt-in über `/skill-activate migration` (kommt in eigener Session)."
tags:
  - skill
  - migration
  - bundle
  - welle-2
scope: vault
bundle_skill: true
default_active:
  allgemein: false
depends_on: []
conflicts_with: []
created: 2026-05-07
updated: 2026-05-15
---

# Migration-Skill

Der Scanner liest den alten Vault ausschließlich (niemals Schreibzugriff), beschränkt sich auf fünf Whitelist-Verzeichnisse und liefert pro Kandidaten-Datei Frontmatter plus erste 20 Zeilen zur Einzelentscheidung. Kein Inhalt wandert ohne explizites „j" in den neuen Vault.

Das Skill ist opt-in: `default_active.allgemein: false`. Es wird erst nach Aktivierung in den Spiegel kopiert — unter Claude Code per `/skill-activate migration`, unter Codex durch direktes Ausführen des Workflows aus `.commands/skill-activate.md`.

## Migrations-Workflow

Der vollständige Datenfluss ist in der Architektur-Spec Sektion 5.4 beschrieben. Kurzfassung:

1. **Scan (read-only):** `scripts/scan_old_vault.py` durchsucht den alten Vault mit harter Pfad-Whitelist und filtert nach Frontmatter-Typen (`kontext`, `prinzip`, `routine`) sowie nach Inhalten in `00 Kontext/`, aktiven Projekten, Bereichen und Ressourcen. Output: JSON-Liste mit Pfad, Typ, Description und Größe.
2. **Filter und Sortierung:** `scripts/candidate_filter.py` wendet optionale Frontmatter-Filter an (z.B. `--only-active-projects`) und sortiert die Kandidaten in die Bearbeitungsreihenfolge.
3. **Übersicht:** Der Agent zeigt dem User eine Kategorien-Zusammenfassung und kündigt an, dass jede Kategorie einzeln durchgegangen wird.
4. **Iteration pro Datei:** Für jede Kandidaten-Datei zeigt der Agent Frontmatter plus erste 20 Zeilen und fragt „Übernehmen? (j/n/anpassen)". Bei „j" wird die Datei in den neuen Vault kopiert, der Pfad angepasst und das `updated`-Feld auf das aktuelle Datum gesetzt (wenn `updated_to_today: true` in der Frontmatter-Config). Bei „n" wird übersprungen. Bei „anpassen" fragt der Agent gezielt nach den gewünschten Änderungen.
5. **Migration-Report:** Am Ende schreibt der Agent `.docs/migration-log.md` mit einer Liste aller übernommenen und übersprungenen Dateien.

## CLI-Beispiele

Scanner starten und Kandidaten nach stdout ausgeben:

```bash
PYTHONUTF8=1 python .skills/migration/scripts/scan_old_vault.py \
    --old-vault /pfad/zum/alten/vault
```

Kandidaten in Datei schreiben:

```bash
PYTHONUTF8=1 python .skills/migration/scripts/scan_old_vault.py \
    --old-vault /pfad/zum/alten/vault \
    --output kandidaten.json
```

Filter: nur Glossar und Schreibstil-Kandidaten:

```bash
PYTHONUTF8=1 python .skills/migration/scripts/candidate_filter.py \
    --input kandidaten.json \
    --category glossar,schreibstil
```

Pipeline: Scan → Filter → nur aktive Projekte:

```bash
PYTHONUTF8=1 python .skills/migration/scripts/scan_old_vault.py \
    --old-vault /pfad/zum/alten/vault | \
PYTHONUTF8=1 python .skills/migration/scripts/candidate_filter.py \
    --only-active-projects
```

## Feature-Flags

Drei Feature-Flags in `skill.config.yaml` steuern das Scan-Verhalten:

- **`include_active_projects_filter`** (Boolean, Default: `true`): Vor der Iteration wird ein `status=aktiv`-Filter auf Projekt-Kandidaten angewendet. Deaktivieren, um auch archivierte Projekte zu erfassen.
- **`include_areas_and_resources`** (Boolean, Default: `true`): Scannt `03 Bereiche/` und `04 Ressourcen/` als Kandidaten-Quellen. Auf `false` setzen für eine Express-Migration (nur Kontext und Projekte).
- **`include_size_limit`** (Boolean, Default: `false`): Wenn `true`, werden Dateien größer als 100 KB ausgeschlossen. Vorbereitung für Welle 3, um LLM-Token-Bomben bei der AI-Review zu vermeiden.

## Konfiguration

Vollständige Konfigurations-Vorlage: `skill.config.example.yaml`. Der Skill arbeitet bewusst auf einem vom User per CLI übergebenem Pfad zum alten Vault (`--old-vault`) — Bundle-Vault-Pfade (`{context}`, `{projects}` etc.) werden in der `paths`-Sektion nicht geführt. Das ist eine Designentscheidung, kein Stub-Artefakt. `cfg.locale` wird für die Ausgabe-Sprache genutzt.

Die `frontmatter`-Sektion enthält `updated_to_today: true` (Boolean) — steuert, ob das `updated`-Feld kopierter Dateien auf das aktuelle Datum gesetzt wird.

## Schreib-Allowlist und Schutzumfang

Der Scanner schreibt **niemals** in den alten Vault zurück. Schutz erfolgt auf zwei Ebenen:

**Statisch:** `scan_old_vault.py` nutzt ausschließlich `Path.read_text(encoding="utf-8")`. Kein `open(..., 'w')`, `write_text`, `write_bytes` oder `append` auf Pfaden unter `--old-vault`.

**Dynamisch (Whitelist):** Nur die folgenden fünf Verzeichnisse werden gescannt:
- `00 Kontext/`
- `02 Projekte/`
- `03 Bereiche/`
- `04 Ressourcen/`
- `08 Systemsteuerung/`

Pfade außerhalb dieser Whitelist auf der obersten Ebene werden ignoriert (kein Fehler, kein Eingriff). `01 Inbox/`, `05 Logbuch/`, `06 Archiv/`, `07 Anhänge/` und alle anderen Verzeichnisse bleiben unberührt.

## Locale

Default: `de`. Einstellbar über `locale` in `skill.config.yaml`. Bestimmt die Ausgabe-Sprache von Meldungen und Kategorien-Übersichten.

## Evals

```bash
PYTHONUTF8=1 python .skills/migration/run_evals.py --verbose
```

Die Eval-Datei liegt unter `eval/migration.eval.json`. Die Eval-Pipeline umfasst Lint-Assertions (SKILL.md-Frontmatter, private Eigennamen, Umlaut-Hygiene), Schema/Loader-Assertions und Behavior-Assertions, die beide Skripte gegen temporäre Fixture-Vaults laufen lassen.

## Verknüpfungen

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