# lawref.delegation

*module*

Делегационная цепочка: основание подзаконного акта → power-норма родителя.

Ступень 2 связей между актами (DECISION-0010). «Акт издан в пределах
компетенции, данной законом» — не семантическое следование (то неразрешимо
статически и живёт в proof graph [§179](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/26-part-xxv-proof-graph-and-explanations.ru.md#179-proof-graph)–187), а КОНЕЧНАЯ проверка цепочки:

1. подчинённый акт объявляет основания — id power-норм родительского пакета
   («издан на основании ст. X закона Y»); их бывает несколько, и каждое
   проверяется отдельно (DECISION-0046);
2. основание разрешается: узел существует и действительно power ([§105.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#1051-базовые-normative-conflict-patterns) п. 4,
   payload норм-шаблона [§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power));
3. power действовала на дату принятия подчинённого акта: хотя бы одна
   редакция родителя применима на эту дату — машина применимости D1
   (`applicability.edition_state`, статусы [§31](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#31-lifecycle)) переиспользуется, а не
   дублируется; её диагностики lifecycle (`LDC-E5302`) пробрасываются;
4. издатель совпадает с holder power.

Как и entrenchment (D4), объявление основания — ДАННЫЕ пакета, а не знание
компилятора. С DECISION-0042 оно живёт в самом CLIR ([§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source) `basis`), а
параметр CLI остался переопределением для гипотез.

Статика сознательно НЕ проверяет:
- validWhen/exercise power — условия осуществления компетенции проверяет
  движок при вычислении ([§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power)–[§128](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#128-immunity));
- смысловое соответствие предмета: сверяется ВКЛЮЧЕНИЕ двух объявленных
  перечислений ([§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source) `regulates` ⊆ [§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power) `subject`, DECISION-0043), а не
  «полномочие охватывает эту норму вообще» — последнее [§105.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#1051-базовые-normative-conflict-patterns) запрещает;
- параметризованный holder (`var`) — статически не сверяем, сверка ложится
  на validWhen при exercise. Раньше этот пропуск был МОЛЧАЛИВЫМ и покрывал
  куда больше объявленного: сверялась ровно одна форма `entity_ref`, которой
  в корпусе нет ни одной — поверхностная константа `.law` лоуверится в
  `const_ref`, и на ЕДИНСТВЕННОЙ форме, что порождает компилятор, проверка
  издателя проходила всегда. Сегодня поимённые формы сверяются обе, а
  несверяемая форма называет себя предупреждением `LDC-W5301`.

Коды [§199](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/27-part-xxvi-static-semantics-and-diagnostics.ru.md#199-diagnostic-code-ranges), диапазон E5 (source/provenance), продолжение за E5301 (D4)
и E5302 (D1).

## lawref.delegation.BASIS_UNRESOLVED_CODE

*attribute* · *module attribute*

```python
BASIS_UNRESOLVED_CODE = 'LDC-E5304'
```

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

## lawref.delegation.CROSS_PACKAGE_CODE

*attribute* · *module attribute*

```python
CROSS_PACKAGE_CODE = 'LDC-W5304'
```

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

## lawref.delegation.EDITION_NOT_PINNED_CODE

*attribute* · *module attribute*

```python
EDITION_NOT_PINNED_CODE = 'LDC-W5303'
```

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

## lawref.delegation.HOLDER_NOT_COMPARABLE_CODE

*attribute* · *module attribute*

```python
HOLDER_NOT_COMPARABLE_CODE = 'LDC-W5301'
```

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

## lawref.delegation.NAMED_HOLDER_KINDS

*attribute* · *module attribute*

```python
NAMED_HOLDER_KINDS = ('entity_ref', 'const_ref')
```

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

## lawref.delegation.NO_BASIS_CODE

*attribute* · *module attribute*

```python
NO_BASIS_CODE = 'LDC-E5303'
```

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

## lawref.delegation.ORGAN_MISMATCH_CODE

*attribute* · *module attribute*

```python
ORGAN_MISMATCH_CODE = 'LDC-E5306'
```

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

## lawref.delegation.POWER_NOT_IN_FORCE_CODE

*attribute* · *module attribute*

```python
POWER_NOT_IN_FORCE_CODE = 'LDC-E5305'
```

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

## lawref.delegation.SUBJECT_EXCEEDED_CODE

*attribute* · *module attribute*

```python
SUBJECT_EXCEEDED_CODE = 'LDC-E5307'
```

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

## lawref.delegation.SUBJECT_NOT_DECLARED_CODE

*attribute* · *module attribute*

```python
SUBJECT_NOT_DECLARED_CODE = 'LDC-W5302'
```

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

## lawref.delegation.adoption_date

*function*

```python
def adoption_date(nodes: list[dict]) -> str | None
```

Дата принятия акта: самое раннее `adopted`-событие его редакций ([§31](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#31-lifecycle)).

У работы одна дата принятия; несколько `adopted` у разных редакций —
следствие консолидаций, принятие акта фиксирует самое раннее.

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

## lawref.delegation.check_delegation

*function*

```python
def check_delegation(sub_nodes: list[dict], parent_nodes: list[dict], *, basis: str | list[str] | None = None, organ: str | None = None, require_basis: bool = False) -> list[dict]
```

Цепочка против ОДНОГО родителя — частный случай `check_delegation_all`.

Форма сохранена: у неё есть потребители (CLI, ворота, MCP), и вызов с одним
родителем остаётся самым частым.

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

## lawref.delegation.check_delegation_all

*function*

```python
def check_delegation_all(sub_nodes: list[dict], parents: list[list[dict]], *, basis: str | list[str] | None = None, organ: str | None = None, require_basis: bool = False) -> list[dict]
```

Проверка цепочки против НЕСКОЛЬКИХ родителей; [] — цепочка цела.

`basis`/`organ` — ПЕРЕОПРЕДЕЛЕНИЕ: по умолчанию и то, и другое берётся из
самого пакета ([§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source) `basis`/`authority`, DECISION-0042), а параметр нужен
там, где акт ещё не объявил основание сам либо проверяется гипотеза «а если
бы издал другой орган». Приём тот же, что у `--protected` D4.

Несколько родителей (DECISION-0048) закрывают границу, объявленную
DECISION-0047 [§5](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/02-part-ii-goals-and-scope.ru.md#5-главные-инварианты-дизайна): пока цепочка брала одного родителя за вызов, половина
предмета акта на двух основаниях всегда оставалась несопоставимой, и
предметная компетенция не устанавливалась НИ ОДНИМ вызовом. Каждое
основание адресуется родителю по пространству имён, звенья «дата» и
«издатель» считаются у своего родителя, а предмет сверяется против
ОБЪЕДИНЕНИЯ предметов всех разрешившихся полномочий — то есть против всей
делегации, а не её половины.

Пустой список НЕ означает правомерности акта в целом: соблюдение
процедуры издания и условий validWhen проверяется отдельно ([§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power)–128,
часть XXI) — здесь только само звено «основание → действовавшая
компетенция → издатель».

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

## lawref.delegation.declared_bases

*function*

```python
def declared_bases(nodes: list[dict]) -> list[str]
```

Основания, объявленные САМИМ актом ([§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source) `basis`, DECISION-0042).

Список, а не одно значение (DECISION-0046): приказ V2000021744 издан «в
соответствии с подпунктом 62) статьи 7 Кодекса ... И пунктом 1 статьи 34
Закона ...», и оснований у акта столько, сколько он назвал. Пока поле было
одиночным, второе основание приходилось выбрасывать — то есть терять
половину делегации молча.

До переноса поля в CLIR основание жило только параметром CLI: знание о
том, на чём акт стоит, не ездило вместе с пакетом. Ровно один
`source_work` — то же ограничение v1, что у темпорального звена ниже.

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

## lawref.delegation.declared_organ

*function*

```python
def declared_organ(nodes: list[dict]) -> tuple[str | None, str | None]
```

Издатель из [§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source) `authority`: (id, форма-которую-не-прочесть).

Возвращает id, если authority назван поимённо (`entity_ref` — форма
самого [§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source), `const_ref` — во что лоуверится константа поверхности), и
имя нечитаемой формы иначе. Второй компонент существует, чтобы
«объявлено, но не прочитано» не выглядело как «не объявлено».

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

## lawref.delegation.declared_subjects

*function*

```python
def declared_subjects(nodes: list[dict]) -> list[str]
```

Предмет акта ([§27.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#271-source) `regulates`, DECISION-0043) — что он регулирует.

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

## lawref.delegation.evidence_gap

*function*

```python
def evidence_gap(parent_nodes: list[dict], adopted: str) -> bool
```

Пробел доказательства ли неприменимость родителя на дату `adopted`.

Различаются ДВА случая, которые до 28.08.2026 схлопывались в один
`LDC-E5305` с формулировкой «издание вне компетенции»:

* родитель на эту дату действительно не действовал (ещё не введён либо
  уже прекращён) — вывод о компетенции, ошибка;
* родитель существовал, но корпус закрепил только ПОЗДНИЕ его редакции —
  сказать о компетенции нечего, и утверждать ultra vires значит называть
  неправомерным то, чего проверка не дочитала.

Признак второго: акт принят ПОСЛЕ принятия родителя, но раньше самого
раннего открывающего события [§31](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/07-part-vii-source-and-document-model.ru.md#31-lifecycle) всех его закреплённых редакций. Именно
так выглядит корпус, пиннящий действующую консолидацию: у Кодекса о
здоровье `adopted @2020-07-07` при `in_force` с 2026 года.

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

## lawref.delegation.find_power

*function*

```python
def find_power(nodes: list[dict], basis: str) -> tuple[dict | None, str | None]
```

Power-норма по id основания: (узел, None) либо (None, причина).

Power распознаётся по `payload.kind == "power"` (форма [§127](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#127-power), как в
T018/T019); `modality` — подтверждающий признак, не замена payload.

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