---
type: skill
agent_ready: true
schema_version: 1
bundle_version: "0.28.0"
name: curator
description: "Dritte Schicht der Karpathy-Compiler-Kette (raw → wiki → index → runtime). Liest proposed-Vorschläge aus der Staging-Datei des Reflectors, bewertet sie gegen Vault-Regeln und Glossar, zeigt Diff-Vorschläge einzeln zur Bestätigung. Einsetzen wenn 'curator', 'staging bewerten', 'Diffs zeigen' oder 'reflector-Vorschläge verarbeiten' erwähnt wird."
tags:
  - skill
  - second-brain
  - curator
  - karpathy
  - wiki-layer
scope: vault
bundle_skill: true
default_active:
  allgemein: true
  karpathy: true
depends_on: [reflector, index-rebuild]
conflicts_with: []
created: 2026-05-12
updated: 2026-05-12
---

# curator

Der Curator ist der letzte Wächter vor der Wiki-Schicht: er liest die Staging-Datei des Reflectors, prüft jeden Vorschlag gegen Glossar und bestehende Einträge und legt ihn dem Nutzer als konkreten Diff vor. Kein Batch-Okay, kein stilles Schreiben. Das Veto-Recht liegt beim Nutzer, nicht beim Skill.

**Der Curator ist der letzte Schutzschild gegen Context Poisoning.** Kein halluziniertes Wissen landet in der Wiki-Schicht, weil der Nutzer jeden Diff sieht. Karpathy-Autonomy-Level: 0.

## Arbeitsteilung LLM vs. Python

Karpathy-Prinzip: deterministische Aufgaben an Software 1.0, semantische Aufgaben an das Modell.

| Aufgabe | Ausführer |
|---|---|
| Proposed-Vorschläge aus Staging extrahieren | `curate.py --mode list-proposed` |
| Glossar- und Dedup-Check, Diff bauen, Zielpfad prüfen | Claude (LLM) |
| Einzelnen Vorschlag vorlegen | Claude (LLM, Chat-Interface) |
| Nach Bestätigung den Edit am Zieldokument ausführen | Claude (LLM, `Edit`-Tool) |
| Staging-Eintrag auf accepted setzen, Log schreiben | `curate.py --mode accept` |
| Bei Ablehnung: Status auf rejected mit Grund | `curate.py --mode reject` |

## Pfade (Bundle-Platzhalter)

Die Pfade werden über den config_loader aus `bundle.json` aufgelöst:

- Staging-Datei (Input vom Reflector): `{system}/Lerner Loop/reflector-staging.md`
- Entscheidungs-Log (Output des Curators): `{system}/Lerner Loop/curator-log.md`

Beide Pfade sind über `skill.config.yaml` überschreibbar (Schlüssel `staging_file` und `log_file` unter `paths:`).

## depends_on-Verhalten (Degradierung)

Der Skill hängt von `reflector` (Staging-Datei) und `index-rebuild` (wird nach accept getriggert) ab.

- **Fehlt die Staging-Datei** (`{system}/Lerner Loop/reflector-staging.md`): `list-proposed` gibt `count: 0` zurück (Graceful-Skip, kein Fehler). `accept` und `reject` geben `{"ok": false, "error": "staging file not found"}` zurück (klare Fehlermeldung, Exit 1).
- **Fehlt `index-rebuild`**: Der Curator ruft `index-rebuild` nach einem `accept` auf. Wenn das Skript fehlt, schlägt nur der Rebuild-Schritt fehl — die Staging- und Log-Updates sind bereits geschrieben. Das LLM meldet den Fehler und fordert den Nutzer auf, `index-rebuild` manuell auszuführen.
- **Unvollständiger Vorschlag in der Staging-Datei** (Pflichtfeld fehlt, z.B. `Typ`): `list-proposed` bricht nicht ab. Der Eintrag wird mit leerem Feld zurückgegeben und das LLM fordert beim Vorlegen die fehlende Information beim Nutzer an, bevor `accept` läuft. Robuste Verarbeitung statt Crash.
- **Schema-Kopplung zu `reflector`**: Das Vorschlags-Block-Format `### Vorschlag #N — <timestamp>` ist Schema-Abhängigkeit von `reflector` — Änderungen an `reflect.py`/`render_proposal` erfordern gleichzeitige Anpassung in `curate.py:PROPOSAL_HEADER_RE`. Beide Skills werden zusammen versioniert und releaset.

## Wann einsetzen

- Nach jedem Reflector-Lauf, sobald mindestens ein proposed-Vorschlag im Staging liegt.
- Auf Zuruf ("Curator durchlaufen", "Staging-Vorschläge zeigen").
- Nie automatisch ohne Nutzer-Bestätigung.

## Ablauf (pro Vorschlag)

1. **Proposed-Vorschläge listen:**
   ```bash
   PYTHONUTF8=1 python .skills/curator/curate.py --mode list-proposed --vault <VAULT_PATH>
   ```
   Gibt ein JSON-Objekt mit `count` und `proposals` auf stdout aus. Jeder Eintrag enthält `number`, `timestamp`, `type`, `source`, `content`, `target`, `reason`, `status`.

2. **Ersten Vorschlag bewerten.** Claude liest die Ziel-Wiki-Datei mit `Read`, prüft das Glossar (`{context}/Glossar.md`) und bestehende Wiki-Einträge. Baut einen konkreten Diff-Vorschlag: Alt-Stand des betroffenen Abschnitts, Neu-Stand, Ein-Satz-Begründung.

3. **Vorlegen.** Struktur:
   ```markdown
   ## Vorschlag #N

   **Ziel:** {resources}/.../Zieldatei.md

   **Alt:**
   > (alter Abschnitt)

   **Neu:**
   > (neuer Abschnitt)

   **Begründung:** Ein Satz.

   Soll ich das übernehmen?
   ```

4. **Antwort abwarten.** `okay`, `ja`, `übernehmen` → accept. `nein`, `verwerfen` → reject (mit Grund). Alles andere → nachfragen.

5. **Bei accept:**
   ```bash
   PYTHONUTF8=1 python .skills/curator/curate.py --mode accept \
     --vault <VAULT_PATH> --number N --reason "<Begründung>"
   ```
   Danach `index-rebuild` aufrufen.

6. **Bei reject:**
   ```bash
   PYTHONUTF8=1 python .skills/curator/curate.py --mode reject \
     --vault <VAULT_PATH> --number N --reason "<Grund>"
   ```

7. **Nächsten Vorschlag bearbeiten** oder stoppen.

## Regeln

- **Kein Schreiben ohne explizites okay pro Vorschlag.** Kein Batch-Okay, kein "akzeptiere alle".
- **Nie mehr als einen Vorschlag gleichzeitig anbieten.** Generation-Verification-Loop: ein Diff, eine Antwort.
- **Glossar-Pflicht.** Jeder Eigenname im Diff wird gegen das Glossar gespiegelt. Abweichungen werden korrigiert, bevor der Diff gezeigt wird.
- **Regel-Check.** Verstößt ein Vorschlag gegen eine Vault-Regel, wird er ohne Rückfrage abgelehnt (mit Grund im Log).
- **Nie `distilled-by: human`-Material anfassen.** Vom Menschen geschriebene Notizen sind tabu.
- **Bei jeder erfolgreichen Wiki-Änderung** unmittelbar danach `index-rebuild` aufrufen.
- **Jede Entscheidung wird geloggt.** `curator-log.md` enthält Zeitstempel, Vorschlags-Nummer, accept/reject, Grund. Append-only.
- **Urteile im Log sind sachlich.** Keine Wertungen über den Reflector.

## Schreib-Allowlist und Schutzumfang

Der Skill schreibt ausschließlich in zwei Pfade: die Staging-Datei (Status-Update bei accept/reject) und die Log-Datei (append-only Entscheidungs-Log). Eine Eval-Assertion prüft `curate.py` statisch auf zwei Schutz-Schichten:

1. **Kein direktes `open(..., 'w'|'a'|'wb'|'ab')`.** Schreiben läuft ausschließlich über `pathlib.Path`.
2. **`write_text`/`write_bytes` nur auf den allowlist-Variablen** (`path`, `staging`, `staging_path`, `log_path`) — alle aus der config_loader-Auflösung der zwei erlaubten paths-Schlüssel.

**Bewusste Grenze:** Eine Umbenennung der Allowlist-Variablen würde diesen statischen Check umgehen. Für volle Garantien wäre AST-Analyse mit Dataflow-Tracking nötig — out of scope für den Bundle-Eval. Ergänzend prüfen die Verhaltens-Assertions (accept/reject auf realem Dateisystem), dass keine Dateien außerhalb der Allowlist entstehen.

## Feature-Flags

Konfigurierbar in `skill.config.yaml` unter `features:`:

| Flag | Typ | Default | Beschreibung |
|---|---|---|---|
| `auto_trigger_index_rebuild` | bool | `false` | Wenn `true`, ruft curate.py nach jedem accept automatisch index-rebuild auf (ohne explizite LLM-Aufforderung). Default `false` (Autonomy-Level 0 bleibt gewahrt). |

## Eval-Set

Eingefrorene Assertions unter `.skills/curator/eval/curator.eval.json`. Der Runner ist `run_evals.py` im Skill-Ordner, arbeitet mit Fixtures in einem Temp-Verzeichnis. Pass-Rate muss 100 Prozent sein.

## Verknüpfungen

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