# lawref.i18n

*module*

Оверлеи меток [§218](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#218-multilingual-ux): переводы объявлений ВНЕ CLIR (DECISION-0070).

Пакет корпуса несёт в исходнике `.law` язык источника и рабочий перевод —
они часть акта формализации и живут в CLIR как метки [§218](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#218-multilingual-ux). Дополнительные
языки отображения в CLIR не вкомпилируются вовсе: файл `i18n/<lang>.json`
рядом с `law.toml` — презентационный слой, который читают вербализатор
(`lawref verbalize --labels …`), MCP и рабочий стол, но НЕ lowering.

Доктринальное основание — [§218](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#218-multilingual-ux)/E-0010: метки вне preimage [§209](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#209-theory-hash-и-artifact-hash), «смена
отображаемого языка не меняет IDs и semantics». Оверлей реализует это ПО
ПОСТРОЕНИЮ: канонические байты CLIR, `check_lower` и differential его не
видят, потому что документ с влитыми метками существует только в памяти
консьюмера. Обратная сторона той же монеты — оверлей адресует узлы по id,
и ссылка может протухнуть молча; поэтому висячий ключ здесь — ГРОМКИЙ отказ
(`apply_overlays` перечисляет все), а корпусные файлы держат ворота
`verify/ci/gates/coverage/check_i18n_overlays.py` с канарейкой.

Формат файла (полный, других ключей нет):

    {
      "formatVersion": "law.i18n/0.1",
      "package": "de.kafka.vor_dem_gesetz",     // имя пакета [§10](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/04-part-iv-project-and-files.ru.md#10-lawtoml) — сверяется
      "language": "en",                          // один язык на файл
      "labels": {
        "Eingang": [{"status": "translation", "text": "entrance to the law"}]
      }
    }

Ключи `labels` — локальные имена узлов (фрагмент id после `#`, включая
процедурные вида `Zutritt/initial`); язык у записей не пишется — он один на
файл и подставляется отсюда. `status` — словарь [§218](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#218-multilingual-ux) (official | unofficial |
translation); у перевода по смыслу `translation`. Морфология `grammaticalForms`
допустима, но словарь слотов [§218.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#2181-grammatical-forms) закрыт по семействам языков — для языков
вне ru/kk/en он пуст, и формы там писать некуда.

Анонимные узлы (`assert-N`) нумеруются позиционно — их переезд перенумеровывает
id; оверлею на такие узлы ссылаться МОЖНО, но хрупкость по датам/порядку
оплачивает автор: ворота назовут висячий ключ первым же прогоном.

## lawref.i18n.FORMAT_VERSION

*attribute* · *module attribute*

```python
FORMAT_VERSION = 'law.i18n/0.1'
```

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L49-L49)

## lawref.i18n.LABEL_STATUSES

*attribute* · *module attribute*

```python
LABEL_STATUSES = ('official', 'unofficial', 'translation')
```

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L52-L52)

## lawref.i18n.apply_overlays

*function*

```python
def apply_overlays(document: dict, overlays: list[dict]) -> dict
```

Влить метки оверлеев в КОПИЮ документа (сам документ не трогается).

Громкие отказы: дефект формы, чужой пакет, висячие ключи (перечисляются
все и по всем оверлеям разом — чинить пачкой дешевле, чем по одному).
Слитый список меток пересортирован ключом lowering-а (language, status,
text), чтобы выбор `verbalize.label_of` работал на нём без оговорок;
точный дубль существующей метки не добавляется — повторное применение
идемпотентно.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L164-L220)

## lawref.i18n.content_hash

*function*

```python
def content_hash(overlay: dict) -> str
```

Пин байтов оверлея для law.lock — sha256 канонических байтов [§208](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#208-canonical-serialization)
(та же форма digest-а, что у A3-ресурсов: `sha256:<hex>`).

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L233-L237)

## lawref.i18n.dangling_keys

*function*

```python
def dangling_keys(document: dict, overlay: dict) -> list[str]
```

Ключи оверлея, не находящие узла в документе (отсортированы).

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L156-L161)

## lawref.i18n.discover_overlays

*function*

```python
def discover_overlays(package_dir: Path) -> list[Path]
```

Файлы оверлеев пакета: `i18n/*.json` рядом с `law.toml`, детерминированно
отсортированные. Каталога нет — пустой список, это не дефект: перевод
опционален, в отличие от метки [§218](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#218-multilingual-ux) в самом акте.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L223-L230)

## lawref.i18n.load_overlay

*function*

```python
def load_overlay(path: Path) -> dict
```

Прочитать и проверить файл оверлея; на дефекте — ValueError со ВСЕМИ
находками разом. Имя файла в каталоге `i18n/` обязано совпадать с языком:
`i18n/en.json` с `"language": "de"` внутри — это две таблички на одной
двери, и ложь одной из них молчалива ровно до первого читателя.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L122-L137)

## lawref.i18n.overlay_labels

*function*

```python
def overlay_labels(overlay: dict) -> dict[str, list[dict]]
```

Материализованные метки [§218](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/30-part-xxix-ux-dx-specification.ru.md#218-multilingual-ux): язык файла подставлен в каждую запись.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L140-L153)

## lawref.i18n.validate_overlay

*function*

```python
def validate_overlay(overlay: object, *, origin: str = 'оверлей') -> list[str]
```

Список дефектов формы (пустой — файл корректен). Ссылки на узлы НЕ
проверяются: для этого нужен документ — см. `dangling_keys`.

[View source](https://github.com-arxohq/arxo-io/law/blob/2edc2b92ce22b52e03f4081d2769a58229684379/engines/lawref/lawref/i18n.py#L62-L119)
