---
title: "Ein Projekt inspizieren"
description: "Nur lesende SDK-Einstiegspunkte hinter doctor, check und diff, dazu Integritätsprüfungen sowie Lock- und Provenienzzustand; keiner schreibt eine Datei."
type: "reference"
---
# Ein Projekt inspizieren

Nur lesende SDK-Einstiegspunkte hinter doctor, check und diff, dazu Integritätsprüfungen sowie Lock- und Provenienzzustand; keiner schreibt eine Datei.

## Zustand inspizieren, ohne zu schreiben [#zustand-inspizieren-ohne-zu-schreiben]

Keine dieser Funktionen übersetzt oder verändert das Lock. Nur `extract` schreibt eine Datei (den
Quellkatalog), und nur `doctor` mit `live` stellt eine Netzwerkanfrage (die Sprachliste des Providers).

### doctor [#doctor]

<AvailableFrom version="0.9.0" />

Prüft die Projekteinrichtung und kostet nichts: Es konstruiert keinen Provider und stellt keine
Netzwerkanfrage, außer `live` fordert eine an, und liest den Wert des API-Keys nur für diese eine
Anfrage nach der Sprachliste (LibreTranslate bekommt keinen Key). Jede Prüfung läuft auch dann, wenn
eine frühere fehlgeschlagen ist, ein Aufruf meldet also jedes unabhängige Problem;
[`verbatra doctor`](https://verbatra.kreitz-webdev.de/de/docs/cli/doctor.md#was-geprüft-wird) listet die Prüfungen auf.

```ts title="Signatur"
function doctor(
  input?: DoctorInput,
  deps?: DoctorDeps,
): Promise<DoctorResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory to search the config from. Defaults to the process working directory. Locale paths resolve against the project root resolveProjectRoot returns: the directory of a config found by the search, otherwise this directory. |
| `configPath` | `string` | no | An explicit config file to validate, bypassing the search. A missing file is an error rather than a failed check. |
| `literals` | `boolean` | no | Run the untranslated-literal scan instead of the setup checks: the config is loaded, then the source roots of its `extract` block are scanned for hardcoded user-facing string literals. No other setup check runs (`format-adapter`, `provider`, `api-key`, `network-policy`, `source-file`, `plural-rules`, `plural-completeness`, `locale-codes`, `locale-state`, `locales`), so no API key environment variable is looked at and a run with no key set can pass. |
| `dataFlow` | `boolean` | no | Describe where the project's data goes instead of running the setup checks: the config is loaded and DoctorResult.dataFlow carries the DataFlowManifest dataFlow builds. Only the `config` and `data-flow` checks run, no API key is read and no network request is made. Takes precedence over DoctorInput.live; ignored when DoctorInput.literals is set. |
| `live` | `boolean` | no | Fetch the configured machine-translation provider's current language list before the `locales` check, instead of judging against the table verbatra ships. It is the one doctor option that sends a network request: to the provider's language list endpoint only (DeepL's `/v3/languages`, Google Cloud Translation's `languages`, or the `languages` endpoint of the configured LibreTranslate server), which uses no translation quota. For DeepL and Google Cloud Translation the request is sent only when the provider's API key variable is set, while LibreTranslate needs no key variable; in every case it is sent only when the network policy permits the provider's host; otherwise, or when the request fails, the static table is used and LocaleCapabilityReport.live says why. It does nothing for an LLM provider or `none`. Ignored on a literal run. Defaults to false. |
| `onProgress` | `ScanProgressListener` | no | Called once after each application source file the `literals` scan reads, with the running count and the total, for progress reporting. |

**Rückgabe:** `DoctorResult`

**Wirft:** [`CONFIG_NOT_FOUND`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#config_not_found)

<AvailableFrom version="0.12.0" />

Die Prüfung `network-policy` schlägt fehl, wenn die wirksame
[Netzwerkrichtlinie](https://verbatra.kreitz-webdev.de/de/docs/network-policy.md) den Host oder Proxy des Providers abweist oder eine
Netzwerk-Variable ungültig ist, und besteht für den Provider `none`. Die informativen Prüfungen
schlagen nie fehl und benennen nichts um; ein `warn` lässt `ok` auf true, und die
[Prüfungstabelle](https://verbatra.kreitz-webdev.de/de/docs/cli/doctor.md#was-geprüft-wird) sagt, was jede nennt und wann sie `skipped` ist.

<AvailableFrom version="0.12.0" />

Die Prüfung `locales` beurteilt jede konfigurierte Locale so, wie es `translate` vor dem Ausgeben
tut: Sie schlägt bei einer nicht unterstützten Locale fehl, ist für `none` `skipped` und liefert die
Urteile in `DoctorResult.locales` als `LocaleCapabilityReport`. Mit `live: true` ruft sie zuerst die
aktuelle Sprachliste des Providers ab, ohne Kontingent zu verbrauchen;
`LocaleCapabilityReport.live` sagt, wie das ausging. Siehe
[Sprachunterstützung](https://verbatra.kreitz-webdev.de/de/docs/language-support.md#unterstützung-vor-einem-lauf-prüfen).

Mit gesetztem `literals` laufen nur die Prüfungen `config` und `untranslated-literals`, wie bei
[`verbatra doctor --literals`](https://verbatra.kreitz-webdev.de/de/docs/cli/doctor.md#nicht-übersetzte-literale). `doctor` lädt die
Konfiguration selbst, ein Projekt ohne Konfiguration bekommt also einen Bericht statt eines
geworfenen Fehlers: `ok` ist genau dann true, wenn keine Prüfung fehlgeschlagen ist, und
`CONFIG_NOT_FOUND` wird nur für einen explizit angegebenen `configPath` geworfen, der nicht existiert.

<AvailableFrom version="0.12.0" />

Nur eine fehlgeschlagene Prüfung trägt `fix`, einen nächsten Schritt im Imperativ; wie `detail`
nennt es Variablen und Pfade, nie den Wert eines Keys.

### dataFlow [#dataflow]

<AvailableFrom version="0.12.0" />

Beschreibt für die geladene Config, wohin die Daten eines Projekts gehen, als versioniertes `DataFlowManifest`. [`verbatra doctor --data-flow`](https://verbatra.kreitz-webdev.de/de/docs/cli/doctor.md#datenfluss) gibt es aus und listet seine Felder; `doctor({ dataFlow: true })` liefert es als `DoctorResult.dataFlow`. Es liest keinen API-Key und macht keinen Netzwerk-Request. Eine ungültige Netzwerk-Variable oder eine nicht lesbare Quelldatei steht im Manifest, statt geworfen zu werden.

```ts title="Signatur"
function dataFlow(
  input?: DataFlowInput,
  deps?: DataFlowDeps,
): Promise<DataFlowManifest>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory to search the config from. Defaults to the process working directory. Every path resolves against the project root resolveProjectRoot returns: the directory of a config found by the search, otherwise this directory. |
| `configPath` | `string` | no | An explicit config file to describe, bypassing the search. |

**Rückgabe:** `DataFlowManifest`

**Wirft:** [`CONFIG_NOT_FOUND`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#config_not_found), [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#config_invalid)

### dataFlowManifestSchema [#dataflowmanifestschema]

<AvailableFrom version="0.12.0" />

Das zod-Schema für ein `DataFlowManifest`, damit ein CI-Schritt oder das Werkzeug eines Reviewers eines validieren kann. Unbekannte Felder bleiben erhalten, da ein neueres verbatra innerhalb von Version 1 Felder ergänzen kann; ignoriere die, die du nicht kennst. `DATA_FLOW_MANIFEST_VERSION` ist die `version`, die dieser Build schreibt.

```ts title="Signatur"
const dataFlowManifestSchema: z.ZodType<DataFlowManifest>;
```

### extract [#extract]

<AvailableFrom version="0.11.0" />

Durchsucht deinen Anwendungscode nach Übersetzungsaufrufen und führt die Funde in den
Quell-Locale-Katalog zusammen, auch wenn es ihn noch nicht gibt. Es konstruiert keinen Provider,
liest keinen API-Key und stellt keine Netzwerkanfrage.

```ts title="Signatur"
function extract(
  input: ExtractInput,
  deps?: ExtractDeps,
): Promise<ExtractResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | A resolved config whose `extract` block names the framework and the source roots. |
| `cwd` | `string` | no | Directory the roots and locale paths are resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `dryRun` | `boolean` | no | Report what would be added without writing anything. |
| `onProgress` | `ScanProgressListener` | no | Called once after each application source file the scan reads, with the running count and the total, for progress reporting. |

**Rückgabe:** `ExtractResult`

**Wirft:** [`EXTRACT_NOT_CONFIGURED`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#extract_not_configured), [`EXTRACT_FS_UNSUPPORTED`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#extract_fs_unsupported), [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`SOURCE_UNWRITABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unwritable)

**Beispiel:** [Keys aus deinem Quellcode extrahieren](https://verbatra.kreitz-webdev.de/de/docs/programmatic-api.md#keys-aus-deinem-quellcode-extrahieren)

Nur wirklich neue Keys werden ergänzt ([Was er schreibt](https://verbatra.kreitz-webdev.de/de/docs/cli/extract.md#was-er-schreibt)). Was
der Scan nicht auflösen kann, kommt als Daten in `dynamic`, `conflicts` und `diagnostics` zurück,
nie geworfen ([Was er meldet](https://verbatra.kreitz-webdev.de/de/docs/cli/extract.md#was-er-meldet-statt-zu-raten)), und das Ergebnis
trägt nie den Inhalt einer Quelldatei.

`config.extract` benennt das Framework und die Quellverzeichnisse. Die Dateisuche braucht das
optionale `readDirectory`-Member von `SdkFs`; ohne es `EXTRACT_FS_UNSUPPORTED`.

### check [#check]

<AvailableFrom version="0.4.0" />

Meldet die Drift pro Locale als Zähler: `missing` (in der Quelle, im Ziel fehlend), `stale`
(Quelle seit der letzten Übersetzung geändert) und `upToDate`. Nutze es als CI-Gate.

```ts title="Signatur"
function check(
  input: CheckInput,
  deps?: CheckDeps,
): Promise<CheckSummary>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |
| `consistency` | `boolean` | no | Also report, per locale, every source string translated more than one way under different keys (see LocaleCheckSummary.inconsistencies). Defaults to false. |
| `qa` | `boolean` | no | Also run the quality check over every committed value (see LocaleCheckSummary.qa): the write-time integrity gate, whose refusals are reported as errors, and the review reasons a translation run computes, reported as warnings. Keyless: no provider is called and nothing is written. Defaults to false. |
| `qaSeverity` | `"error" \| "warning"` | no | The lowest severity the quality check reports. `error` skips the review reasons entirely, so only integrity failures are reported. Ignored unless CheckInput.qa is true. Defaults to `warning`. |
| `requireReviewed` | `boolean` | no | Also run the review gate (see CheckSummary.review): every value written by a machine-class path (see MACHINE_CLASS_ORIGINS) must be approved in the provenance file. A value a person wrote, imported, or edited outside verbatra needs no approval, and neither does one with no provenance record. An approval given against a source text that has changed since does not count. Keyless: no provider is called and nothing is written. Defaults to false. |
| `sensitive` | `boolean` | no | Also scan the source file and the glossary of every reported locale for content that looks sensitive (see CheckSummary.sensitive), with the config's `sensitiveData` detectors, patterns and allow list, or the default detectors when the block is absent. It scans every field a language model would receive, whatever the configured provider and `sensitiveData.mode`. Keyless: no provider is called and nothing is written. Defaults to false. |

**Rückgabe:** `CheckSummary`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale)

**Beispiel:** [In CI prüfen, ohne zu schreiben](https://verbatra.kreitz-webdev.de/de/docs/programmatic-api.md#in-ci-prüfen-ohne-zu-schreiben)

`inSync` ist genau dann true, wenn jede geprüfte Locale nichts Fehlendes und nichts Veraltetes hat.

<AvailableFrom version="0.11.0" />

Mit `consistency: true` trägt jede `LocaleCheckSummary` zusätzlich `inconsistencies`: eine
`InconsistencyGroup` pro Quellstring, den die Locale unter verschiedenen Keys unterschiedlich
übersetzt, in der Form, die der [Konsistenzbericht](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#konsistenzbericht) zeigt. Es ist
nur ein Bericht: Er ändert nie `inSync`, einen Zähler oder eine Datei.

<AvailableFrom version="0.12.0" />

Jede `LocaleCheckSummary` trägt außerdem `provenance`: Zähler `byOrigin` und `byReviewState` über
die Keys, für die die Locale einen Wert hat, gelesen aus `verbatra.provenance.json`
([Herkünfte](https://verbatra.kreitz-webdev.de/de/docs/the-lock-file.md#herkunft-wer-welchen-wert-geschrieben-hat)). Dieses und jedes
andere Herkunftsfeld eines Berichts fehlt, statt einen Fehler auszulösen, wenn die Datei beschädigt
ist oder von einem neueren verbatra stammt.

<AvailableFrom version="0.12.0" />

Jede `LocaleCheckSummary` enthält außerdem `protected`, den Anteil von `stale`, den ein `translate`-Lauf unter `humanEdits` und `pinnedKeys` für einen Menschen übrig lassen würde ([Geschützte Keys](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#geschützte-keys)). Sie zählen weiter als veraltet, also bleibt `inSync` false, bis ein Mensch sie auflöst; ein fehlender gepinnter Key zählt nur als fehlend.

<AvailableFrom version="0.12.0" />

Mit `qa: true` lässt `check` zusätzlich die [Qualitätsprüfung](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#qualitätsprüfung)
über jeden eingecheckten Wert laufen, ohne Key und ohne zu schreiben: Jede `LocaleCheckSummary`
trägt einen `qa`-Bericht und die Zusammenfassung die `qa`-Summen, in den Formen dieses Abschnitts.
Fehlergründe stammen aus `INTEGRITY_GATE_REASONS`, Warngründe aus `REVIEW_REASON_CODES`,
Schweregrade aus `QA_SEVERITIES`; `qaSeverity: "error"` lässt Warnungen weg. `inSync` ändert sich
nie: Ein CI-Gate liest `qa.errors`, streng auch `qa.warnings`.

<AvailableFrom version="0.12.0" />

Jede `LocaleCheckSummary` trägt außerdem `incompletePlurals`, nach Key sortiert: ein `IncompletePlural`
`{ code: "PLURAL_CATEGORIES_INCOMPLETE", key, argument?, ruleType, missing }` pro Plural, dem
CLDR-Kategorien der Zielsprache fehlen. Nur eine Warnung; Formate und Regeln stehen unter
[Pluralkategorien](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#pluralkategorien).

Mit `requireReviewed: true` führt `check` zusätzlich das
[Review-Gate](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#freigegebene-übersetzungen-verlangen) aus, ohne Key und ohne zu
schreiben: Jede `LocaleCheckSummary` trägt `review: { unreviewed }`, die nicht freigegebenen
maschinellen Keys, und die Zusammenfassung trägt `review: { reviewed, unreviewed, code? }` mit den
Codes, die dieser Abschnitt nennt. Der Bericht ändert `inSync` nie; ein CI-Gate liest
`review.reviewed`.

<AvailableFrom version="0.12.0" />

Mit `sensitive: true` führt `check` außerdem den Scan auf
[sensible Inhalte](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#sensible-inhalte) aus, ohne Key und ohne zu schreiben: Die
Zusammenfassung trägt `sensitive: { findings, glossaryTerms }`, ein `{ key, fields, detectors }` pro
gemeldetem Key, nie den gefundenen Text. Ein CI-Gate scheitert an beidem.

### checkFile [#checkfile]

<AvailableFrom version="0.12.0" />

Prüft eine einzelne Locale-Datei direkt nach einer Änderung durch eine Person oder einen Agenten.
Es liest nur diese Datei und, für eine Ziel-Locale, die Quelldatei; es ruft keinen Provider auf,
liest keinen API-Key und schreibt nichts.

```ts title="Signatur"
function checkFile(
  input: CheckFileInput,
  deps?: CheckFileDeps,
): Promise<CheckFileSummary>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` and CheckFileInput.file are resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `file` | `string` | yes | The locale file to check, absolute or relative to the working directory. |
| `qaSeverity` | `"error" \| "warning"` | no | The lowest severity to report. `error` skips the review reasons, so only syntax and integrity failures are reported. Defaults to `warning`. |

**Rückgabe:** `CheckFileSummary`

**Wirft:** [`NOT_A_LOCALE_FILE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#not_a_locale_file), [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid)

`file` ist absolut oder relativ zu `cwd`; [Eine Datei](https://verbatra.kreitz-webdev.de/de/docs/cli/check.md#eine-datei) zeigt die Form der
`CheckFileSummary`. Eine Zieldatei wird wie bei `check` mit `qa: true` geprüft, die Quelldatei nur
auf ihre Syntax. Eine Datei, die sich nicht parsen lässt, wird nicht geworfen: Ihre Locale trägt
einen `QaSyntaxFinding`, bei JSON und YAML mit der Position, die `AdapterError.position` meldet. Ein
Pfad, der zu keinem konfigurierten Locale gehört, oder eine fehlende Datei wirft `NOT_A_LOCALE_FILE`.

### diff [#diff]

<AvailableFrom version="0.4.0" />

Das detaillierte Gegenstück zu `check`: dieselbe Berechnung, aber es gibt die Key-Listen pro
Locale zurück (`missing`, `changed`, `orphaned`) statt Zähler. Verwaiste Keys sind reine Meldung
und kippen nie `hasPendingChanges`, da ein Standardlauf kein `prune` ausführt.

```ts title="Signatur"
function diff(
  input: DiffInput,
  deps?: DiffDeps,
): Promise<DiffSummary>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |
| `unused` | `boolean` | no | Also scan the application source configured in the `extract` block and report the source-catalog keys nothing references, as DiffSummary.unused. Off by default. |
| `onProgress` | `ScanProgressListener` | no | Called once after each application source file the `unused` scan reads, with the running count and the total, for progress reporting. |

**Rückgabe:** `DiffSummary`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale)

**Beispiel:** [In CI prüfen, ohne zu schreiben](https://verbatra.kreitz-webdev.de/de/docs/programmatic-api.md#in-ci-prüfen-ohne-zu-schreiben)

Mit `unused: true` scannt es zusätzlich die `extract`-Roots der Konfiguration, nur lesend und ohne
Key, und ergänzt einen `unused`-Bericht der Quell-Keys, die keine statische Referenz nennt, getrennt
von jeder `orphaned`-Liste und ohne je `hasPendingChanges` zu kippen;
[Ungenutzte Quell-Keys](https://verbatra.kreitz-webdev.de/de/docs/cli/diff.md#ungenutzte-quell-keys) erklärt seine Felder.

<AvailableFrom version="0.12.0" />

Jedes `LocaleDiff` trägt außerdem `changedOrigins`, die Herkunft des aktuellen Werts jedes
`changed`-Keys (etwa `machine`, `human` oder `external`): wessen Arbeit eine Neuübersetzung ersetzen würde.

<AvailableFrom version="0.12.0" />

Jedes `LocaleDiff` enthält außerdem `protected`, die fehlenden und geänderten Keys, die ein `translate`-Lauf in Ruhe lassen würde, sortiert; sie zählen weiter als ausstehend.

### keyIntegrity [#keyintegrity]

<AvailableFrom version="0.5.0" />

Meldet für die geänderten Keys jeder Locale, ob der aktuelle Zielwert noch zu den Platzhaltern und
dem Inline-Markup der Quelle passt und gültiges ICU ist: Jeder Eintrag trägt `key`,
`hasPlaceholders`, `matches`, bei einer Abweichung die `missing`- und `extra`-Tokens, `icuValid`,
`markupMatches` und `markupDetails`, nie einen String-Wert. Werte, die vor dem Gate beim Schreiben
entstanden oder außerhalb von verbatra bearbeitet wurden, werden gleich beurteilt. Studio zeigt
diesen Bericht pro Key an.

```ts title="Signatur"
function keyIntegrity(
  input: KeyIntegrityInput,
  deps?: KeyIntegrityDeps,
): Promise<readonly LocaleKeyIntegrity[]>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |
| `keys` | `readonly string[]` | no | Restrict the report to these keys. Each must exist in the source resource. Only keys the diff reports as changed are ever judged, so a requested key whose translation is missing or up to date is left out rather than reported. Defaults to every changed key. |

**Rückgabe:** `readonly LocaleKeyIntegrity[]`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale), [`UNKNOWN_KEY`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_key)

<AvailableFrom version="0.12.0" />

Jeder Eintrag trägt außerdem `icuArmsMatch` und `icuArmDetails`: ob die ICU-Zweige für `plural`,
`selectordinal` und `select` des Werts zur Zielsprache passen, so beurteilt wie beim
[Gate beim Schreiben](https://verbatra.kreitz-webdev.de/de/docs/translation-safety.md#plural-zweige-je-zielsprache), mit einem kurzen
Problem pro falschem Zweig. `icuArmsMatch` ist immer true für ein Format, das keine Zweige prüft.

`keys` engt die Prüfung ein; geprüft werden immer nur Keys, die für eine Locale "geändert" sind.

### localeIntegrity [#localeintegrity]

<AvailableFrom version="0.12.0" />

Findet jede Übersetzung in den Ziel-Locales, die gerade kaputt ist: ein verlorener oder ergänzter
Platzhalter oder Inline-Markup, ungültiges ICU oder ICU-Zweige, die nicht zur Zielsprache passen.
Anders als `keyIntegrity` beurteilt es jeden Key, der in der Quelle und in einer Ziel-Locale
vorkommt, egal wie sein Sync-Zustand ist, nach denselben Regeln, und gibt nur fehlerhafte Keys
zurück: Eine leere `entries`-Liste heißt, dass die Locale besteht.

```ts title="Signatur"
function localeIntegrity(
  input: LocaleIntegrityInput,
  deps?: LocaleIntegrityDeps,
): Promise<readonly LocaleKeyIntegrity[]>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |

**Rückgabe:** `readonly LocaleKeyIntegrity[]`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale)

Jeder Aufruf liest und parst die Quelldatei und jede angefragte Zieldatei frisch, ohne Cache.

### lockState [#lockstate]

<AvailableFrom version="0.5.0" />

Meldet für die Lock-Datei Existenz, Version und Drift pro Locale (Baseline-Key-Anzahl plus Zähler
für fehlend, veraltet und aktuell). `exists` stammt aus einer expliziten Prüfung, sodass eine
fehlende und eine leere Lock-Datei unterscheidbar bleiben; fehlt sie, ist das Ergebnis
`{ exists: false }` und nichts weiter wird gelesen.

```ts title="Signatur"
function lockState(
  input: LockStateInput,
  deps?: LockStateDeps,
): Promise<LockStateResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |

**Rückgabe:** `LockStateResult`

**Wirft:** [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid), [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid)

Jede Locale trägt außerdem dieselben `provenance`-Zähler, die `check` meldet.

### loadLockFile [#loadlockfile]

<AvailableFrom version="0.5.0" />

Liest die Lock-Datei selbst (`verbatra.lock.json`, auch als `LOCK_FILE_NAME` exportiert) und gibt
ihre geparste Form zurück: `{ version, locales }`, wobei jede Locale Keys auf den Hash des
Quellinhalts abbildet, aus dem sie zuletzt übersetzt wurden. Eine fehlende Datei fällt auf ein
leeres Lock zurück, dasselbe Erstlauf-Verhalten, auf das sich `translate` verlässt; nutze
`lockState`, wenn du Abwesenheit unterscheiden musst.

```ts title="Signatur"
function loadLockFile(
  input?: LoadLockFileInput,
  deps?: LoadLockFileDeps,
): Promise<LockFile>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory holding the lock-file. Defaults to the process working directory, even when the config was found in a parent directory: pass the root resolveProjectRoot returns. |

**Rückgabe:** `LockFile`

**Wirft:** [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid)

Keine Konfiguration nötig.

### loadProvenance [#loadprovenance]

<AvailableFrom version="0.12.0" />

Liest die Herkunftsdatei selbst (`verbatra.provenance.json`, auch als `PROVENANCE_FILE_NAME`
exportiert) und gibt ihre gespeicherte Form zurück: `{ version, locales }`, wobei jede Locale Keys
auf einen Eintrag `{ origin, provider?, model?, valueHash, reviewState?, reviewer?, reviewedSourceHash? }` abbildet, ohne
übersetzten Text. Eine fehlende Datei oder eine von einem neueren verbatra liest sich als leer; eine
korrupte wirft `PROVENANCE_FILE_INVALID`. `keyValue`, `localeValues`, `check`, `diff` und
`lockState` melden die ausgewertete Sicht (`KeyProvenance`), die auch `unrecorded` von `external`
unterscheidet.

```ts title="Signatur"
function loadProvenance(
  input?: LoadProvenanceInput,
  deps?: LoadProvenanceDeps,
): Promise<ProvenanceFile>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory holding the provenance file. Defaults to the process working directory, even when the config was found in a parent directory: pass the root resolveProjectRoot returns. |

**Rückgabe:** `ProvenanceFile`

**Wirft:** [`PROVENANCE_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#provenance_file_invalid)

Keine Konfiguration nötig.

### runStatus [#runstatus]

<AvailableFrom version="0.5.0" />

Liest den Schnappschuss aus Review-Flags und Token-Verbrauch, den der letzte `translate`- oder
`watch`-Lauf ohne Dry-Run nach `.verbatra-local/run-status.json` persistiert hat. Wirft nie: eine
unbrauchbare Datei fällt auf `available: false` zurück. Die Datei ist Best-Effort-Telemetrie, keine
Korrektheits-Baseline.

```ts title="Signatur"
function runStatus(
  input?: RunStatusInput,
  deps?: RunStatusDeps,
): Promise<RunStatusResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory holding the `.verbatra-local` status directory. Defaults to the process working directory, even when the config was found in a parent directory: pass the root resolveProjectRoot returns. |

**Rückgabe:** `RunStatusResult`

Keine Konfiguration nötig. Gibt `{ available: false, reason }` (siehe `RUN_STATUS_UNAVAILABLE_REASONS`)
oder `{ available: true, version, generatedAt, usage?, budget?, locales }` zurück.

Ein Schnappschuss von vor dem durchgesetzten Token-Budget wird weiter gelesen, ohne ein `budget` mit
`supported: false` (sein `tokensUsed: 0` war keine Zählung). Neue Schnappschüsse ergänzen nur ein
Markierungsfeld, sodass ein älterer Leser ein geschätztes Budget eventuell als nicht erfasst zeigt.
Ein unbekannter Review-Grund wird ignoriert, und ein Eintrag ohne bekannten Grund entfällt.

### reviewQueue [#reviewqueue]

<AvailableFrom version="0.12.0" />

Liest die Review-Warteschlange aus den committeten Dateien: jeden Key, dessen aktueller Wert eine
maschinelle Herkunft hat (`machine`, `memory`, `fuzzy` oder `agent`, das Tupel
`MACHINE_CLASS_ORIGINS`) und nicht freigegeben ist, pro Ziel-Locale in der Reihenfolge der Quelle.
Sie liest die Locale-Dateien, `verbatra.lock.json` und `verbatra.provenance.json`, also sehen alle
mit demselben Commit dieselbe Warteschlange. Ein Key verlässt sie, sobald sein Wert freigegeben oder
abgelehnt ist oder eine Person einen neuen Wert schreibt oder importiert; ein Wert, den ein Agent neu
geschrieben hat, bleibt, ebenso eine Freigabe von vor einer Änderung der Quelle. Der letzte
`runStatus`-Schnappschuss ergänzt nur Details: die `reasons` jedes Eintrags (leer, wenn der Lauf ihn
nicht mit einem bekannten Grund markiert hat), die `fuzzyHits` der Locale und `lastRunAt`.

```ts title="Signatur"
function reviewQueue(
  input: ReviewQueueInput,
  deps?: ReviewQueueDeps,
): Promise<ReviewQueueResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the queue to these target locales. Defaults to every configured target locale. |
| `includeApproved` | `boolean` | no | Also list, per locale, the machine-class values already approved (see ReviewQueueLocale.approved), for a reviewer who wants to revisit them. Defaults to false. |

**Rückgabe:** `ReviewQueueResult`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid)

**Beispiel:** [Die Review-Warteschlange abarbeiten](https://verbatra.kreitz-webdev.de/de/docs/programmatic-api.md#die-review-warteschlange-abarbeiten)

Gibt `{ available: true, locales, lastRunAt? }`
zurück, jede Locale als `{ locale, needsReview, approved?, fuzzyHits? }` und jeden Eintrag als
`{ key, reasons, provenance }`; `approved` listet die freigegebenen maschinellen Werte und ist nur mit
`includeApproved: true` vorhanden. Ist die Herkunftsdatei beschädigt oder stammt sie von einer
neueren verbatra-Version, gibt sie `{ available: false, reason: "provenance-unreadable" }` zurück.
Eine Quell-, Ziel- oder Lock-Datei, die sich nicht lesen lässt, lässt den Aufruf scheitern wie bei
`check`. Bis 0.11 bestand die Warteschlange nur aus den Markierungen des letzten Laufs.

### provenanceReport [#provenancereport]

<AvailableFrom version="0.12.0" />

Erstellt den Bericht pro Locale, den `verbatra report provenance` ausgibt: jeden Key mit einem Wert
sowohl in der Quelle als auch in einer Ziel-Locale, in der Reihenfolge der Quelle, mit Herkunft,
Review-Status, Provider, Modell und Reviewer, gezählt in einer `PROVENANCE_BUCKETS`-Kategorie
([der Herkunftsbericht](https://verbatra.kreitz-webdev.de/de/docs/provenance-evidence.md#der-herkunftsbericht) definiert sie). Er ruft
keinen Provider auf und schreibt nichts.

```ts title="Signatur"
function provenanceReport(
  input: ProvenanceReportInput,
  deps?: ProvenanceReportDeps,
): Promise<ProvenanceReportResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |
| `toolVersion` | `string` | no | The verbatra version to stamp on the report, as ProvenanceReport.toolVersion. Defaults to `unknown`. |

**Rückgabe:** `ProvenanceReportResult`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid)

`deps` nimmt außerdem `now`, die Uhr für `generatedAt`. Die vollständige Form des Ergebnisses steht
im [JSON-Schema](https://verbatra.kreitz-webdev.de/de/docs/provenance-evidence.md#das-json-schema). Ist die Herkunftsdatei beschädigt oder
stammt sie von einem neueren verbatra, gibt er `{ available: false, reason: "provenance-unreadable" }`
zurück, da jeder Wert als `unrecorded` gälte. Eine Quell-, Ziel- oder Lock-Datei, die sich nicht
lesen lässt, lässt den Aufruf scheitern wie bei `check`. Der Bericht ist ein unterstützender
Nachweis, keine Rechtsberatung.

### provenanceReportPage [#provenancereportpage]

<AvailableFrom version="0.12.0" />

Baut denselben Bericht wie `provenanceReport` und gibt seine Einträge seitenweise zurück, optional nur die aus bestimmten `buckets`, mit einem Cursor für die nächste Seite. Jede Seite behält `total` und `counts` jeder Locale vollständig. `report.provenance` im MCP-Server blättert damit. Nur lesend.

```ts title="Signatur"
function provenanceReportPage(
  input: ProvenanceReportPageInput,
  deps?: ProvenanceReportDeps,
): Promise<ProvenanceReportPageResult>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `buckets` | `array` | no | List only the entries in these buckets. The counts always cover every bucket. |
| `limit` | `number` | no | The most entries the page holds, a whole number from 1 to PAGE_LIMIT_CAP. Defaults to PAGE_LIMIT_DEFAULT. |
| `cursor` | `string` | no | The `nextCursor` of the previous page. Omit it to read the first page. |
| `config` | `VerbatraConfig` | yes | The resolved project config, normally from loadConfig. |
| `cwd` | `string` | no | Directory the `files.pattern` is resolved against. Defaults to the project root of the config object loadConfig returned, else the process working directory; a copied or rebuilt config loses that root, so pass `cwd` from resolveProjectRoot. |
| `locales` | `readonly string[]` | no | Restrict the report to these target locales. Defaults to every configured target locale. |
| `toolVersion` | `string` | no | The verbatra version to stamp on the report, as ProvenanceReport.toolVersion. Defaults to `unknown`. |

**Rückgabe:** `ProvenanceReportPageResult`

**Wirft:** [`UNKNOWN_FORMAT`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_format), [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#unknown_locale), [`LOCALE_LAYOUT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_layout_invalid), [`LOCALE_PATH_COLLISION`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_path_collision), [`SOURCE_UNREADABLE`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_unreadable), [`SOURCE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#source_invalid), [`LOCK_FILE_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#lock_file_invalid), [`PAGE_CURSOR_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#page_cursor_invalid), [`PAGE_LIMIT_INVALID`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#page_limit_invalid)

Eine Locale trägt `entries` nur auf den Seiten, die einen ihrer Einträge enthalten. Eine Seite hält höchstens `limit` Einträge, standardmäßig `PAGE_LIMIT_DEFAULT`; gib `nextCursor` mit denselben `locales` und `buckets` als `cursor` zurück, bis er fehlt. Er ist genau dann nicht verfügbar oder schlägt fehl, wenn `provenanceReport` es tut.
