vault validate

Prüft einen Vault gegen die Apparat-Spezifikation und gibt einen Report aus. Pflichtfelder werden hart geprüft, Konventionsbrüche erzeugen Warnungen. Das Kommando ändert nichts — es liest nur und berichtet.

Einfachster Fall

apparat vault validate

Wenn alles sauber ist:

Vault "recherche" is clean — 42 file(s) scanned, no findings.

Wenn es etwas zu berichten gibt:

Vault "recherche" — validation findings:

content/2026-04-19--maria-beispiel--V1StGXRa.md
  ERROR  id.filename_mismatch       Field `id` "Bx7tYu3v" does not match the NanoId suffix "V1StGXRa" in the filename.
  WARN   type.case                  Type value "Person" should be lowercase.

content/2026-04-20--wcag--BbBbBbBb.md
  WARN   key.case                   Frontmatter key "birthDate" is not snake_case.

assets/stray-file.pdf
  ERROR  asset.schema               Asset filename "stray-file.pdf" does not match the schema YYYY-MM-DD--slug--nanoid.ext.

Summary: 2 errors, 2 warnings across 44 file(s) scanned, 41 clean (errors).

Jede Zeile: Severity (ERROR oder WARN), Rule-ID (maschinenlesbar, z.B. id.missing, type.case), Beschreibung.

Exit-Codes

Code Bedeutung
0 Sauber — keine Fehler, keine Warnungen
1 Mindestens ein harter Fehler
2 Nur Warnungen, keine harten Fehler

So kann ein CI-Skript zwischen „blockend" und „kosmetisch" unterscheiden:

apparat vault validate
case $? in
  0) echo "clean" ;;
  1) echo "errors — do not ship"; exit 1 ;;
  2) echo "warnings only — proceeding, but clean up soon" ;;
esac

Maschinenlesbare Ausgabe: --json

apparat vault validate --json

Gibt ein einzelnes JSON-Objekt auf stdout aus, das den vollständigen Report enthält:

{
  "vault": {
    "name": "recherche",
    "url": "https://apparat.example.com/vaults/recherche",
    "path": "/home/max/vaults/recherche"
  },
  "summary": {
    "errors": 2,
    "warnings": 2,
    "files_scanned": 44,
    "files_clean": 41
  },
  "findings": [
    {
      "severity": "error",
      "file": "content/2026-04-19--maria-beispiel--V1StGXRa.md",
      "rule": "id.filename_mismatch",
      "message": "Field `id` \"Bx7tYu3v\" does not match the NanoId suffix \"V1StGXRa\" in the filename."
    },
    ...
  ]
}

Der Exit-Code ist derselbe wie im Textmodus. Praktisch für:

Vault-Auswahl

Wie bei allen Read-Kommandos: ohne --vault greift die übliche Auto-Lokalisierung (CWD-Erkennung, einziger registrierter Vault, interaktive Auswahl). Explizit:

apparat vault validate --vault=arbeit
apparat vault validate --vault=/home/max/vaults/recherche
apparat vault validate --vault=https://apparat.example.com/vaults/recherche

Was geprüft wird

Harte Fehler (Exit-Code 1)

Das sind Zustände, die verhindern, dass die Datei als reguläre Entität behandelt werden kann. Dieselben Dateien erscheinen als irregulär in vault irregular und lassen sich mit entity import in den regulären Bestand überführen.

Rule-ID Bedeutung
file.schema Content-Dateiname folgt nicht YYYY-MM-DD--slug--nanoid.md
frontmatter.missing Datei hat kein YAML-Frontmatter-Block
frontmatter.parse Frontmatter ist syntaktisch kaputt
id.missing Pflichtfeld id fehlt oder ist leer
id.format id entspricht nicht dem NanoID-Format [A-Za-z0-9]{8}
id.filename_mismatch id im Frontmatter und NanoID im Dateinamen stimmen nicht überein
type.missing Pflichtfeld type fehlt oder ist leer
created.missing Pflichtfeld created fehlt
created.format created ist kein ISO-Datum (YYYY-MM-DD)
language.missing Pflichtfeld language fehlt oder ist leer
language.format language entspricht nicht dem BCP-47-Subset ^[a-z]{2,3}(-[A-Z]{2})?$
asset.schema Asset-Dateiname folgt nicht YYYY-MM-DD--slug--nanoid.ext

Warnungen (Exit-Code 2)

Konventionsbrüche, die nichts kaputt machen, aber eine aufräumwürdige Drift signalisieren.

Rule-ID Bedeutung
key.case Frontmatter-Schlüssel ist nicht snake_case (z.B. birthDate statt birth_date)
key.charset Schlüssel enthält Bindestrich, Leerzeichen oder Umlaut
key.language Schlüssel sieht deutsch aus (titel, autor, datum, Umlaute)
type.case type-Wert enthält Großbuchstaben (Person statt person)
string.length Einzelner String-Wert ist länger als 500 Zeichen (klingt nach Fließtext im falschen Feld)
link.orphan Ein Fließtext-Link zeigt auf eine NanoID, die weder als Entität noch als Asset im Vault existiert.
relation.broken Ein Frontmatter-Beziehungs­eintrag (works_at: Xxx, knows: [...]) zeigt auf eine NanoID, die es im Vault nicht gibt.
asset.orphan Ein Asset unter assets/ wird weder im Fließtext eingebettet noch in einer representations:-Liste referenziert — es gehört zu keiner Entität.
journal.stale Eine Datei unter .apparat/journal/ ist älter als 24 Stunden. Hinweis auf eine steckengebliebene Multi-Datei-Operation, die keine automatische Recovery einsammeln konnte (z. B. weil das Kommando, das sie startete, heute einen anderen Operations-Namen kennt).
journal.malformed Das Journal-Verzeichnis oder eine einzelne Journal-Datei lässt sich nicht lesen bzw. dekodieren — etwa weil die Datei kein gültiges JSON enthält oder ihr Startzeitpunkt kein lesbares Datum ist.
asset.sidecar_missing Ein Asset unter assets/ hat keine <dateiname>.sha256-Datei. Apparat nutzt diese Sidecar-Datei, um Duplikate beim Import zu erkennen. Heilung: apparat graph rebuild schreibt fehlende Sidecars nach.
asset.sidecar_orphan Eine .sha256-Datei liegt im assets/-Verzeichnis, ohne dass die zugehörige Asset-Datei existiert. Heilung: die verwaiste Sidecar-Datei manuell löschen.
asset.sidecar_drift Der in der Sidecar-Datei gespeicherte Hash stimmt nicht mehr mit dem aktuellen Asset-Inhalt überein. Hinweis auf Bit-Rot oder einen externen Eingriff in die Datei. Heilung: Asset-Inhalt prüfen, danach Sidecar löschen und apparat graph rebuild lassen.
asset.sidecar_malformed Eine .sha256-Datei existiert, enthält aber keinen gültigen SHA-256-Wert. Heilung: Sidecar löschen, apparat graph rebuild schreibt sie korrekt nach.

Was außerhalb des Validators liegt

Drei Klassen von Befunden werden vom Validator bewusst nicht angefasst:

Abgrenzung zu anderen Kommandos

vault validate arbeitet rein lesend — der Vault wird nicht verändert, weder Inhalte noch Zeitstempel. Für gezielte Sanierung gibt es vault irregular und entity import. Der Trash hat seine eigene Listing-Ansicht (vault trash list) und wird vom Validator nicht mitgeprüft.

Verwandte Themen