# lawref.amend

*module*

Синтез минимальной поправки — L8.3 плана LAYERS-NEXT (горизонт [§5](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/02-part-ii-goals-and-scope.ru.md#5-главные-инварианты-дизайна),
заведён поручением владельца; см. spec/decisions/0035-loophole-and-amend.ru.md).

Вход — пакет, целевые исходы (сценарии с ожидаемым truth status) и
регрессионные сценарии, чьи исходы меняться не должны. Выход — минимальный
по числу операций набор МЕХАНИЧЕСКИХ правок документа, при котором каждый
целевой сценарий даёт ожидание, а каждый регрессионный — байтово тот же
исход (проекция О-1: {results, positions, conflicts, issues}). «Поправка
как PR»: к находке прикладывается impact-отчёт О-1 до→после.

Оркестрация без семантики (инвариант CLAUDE.md №5): правки — операции над
СТРУКТУРОЙ документа (снять узел, снять поле, добавить узел готовой формы),
их смысл нигде не интерпретируется — каждый кандидат ИСПОЛНЯЕТСЯ обоими
классами сценариев через `impact.run_scenario`, и решают канонические байты
исходов [§208](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/28-part-xxvii-canonical-legal-ir.ru.md#208-canonical-serialization). Прецедент — reanchor (спутник О-2): инструмент предлагает
кандидатов механически, проверяет исполнением.

Пространство операций (DECISION-0035, DECISION-0178; каждый кап назван):

- `remove_rule` — снять правило; каскадом снимаются priority_rule [§116](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/17-part-xvi-priority-declarations.ru.md#116-direct-priority),
  ссылающиеся на него (иначе повисшая ссылка — ровно тот вис, который
  диагностирует edition_projection);
- `remove_priority` — снять priority_rule [§116](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/17-part-xvi-priority-declarations.ru.md#116-direct-priority);
- `drop_effective` — снять окно `effective` [§87](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/12-part-xii-events-actions-temporal-model.ru.md#87-rule-temporal-qualifiers) у правила (норма действует
  на всей оси времени);
- `exclude_enum_value` — добавить к телу исключение одного enum-значения
  из подстановки proof-графа; остальные члены перечня проверяются автоматически;
- `add_priority` — добавить priority_rule [§106](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#106-priority-relation) на упорядоченную пару правил;
  пары не выдумываются, а добываются из ВЫХОДА движка: участники [§115](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/16-part-xv-defeasible-semantics-and-conflict-resolution.ru.md#115-конфликтный-результат)-
  конфликтов целевых сценариев на базовом документе (rule_application из
  proof-графа, как в фаззере О-4).

Не входит (открытая часть исследовательской задачи, названная в плане):
свободный синтез правил и формул, правка скаляров, операции над норм-шаблонами.
Автопроверка ограничена одной enum-осью при остальных фиксированных входах.

Поиск детерминирован без PRNG: полный перебор наборов операций по
возрастанию мощности (1 … max_edits) в порядке канонических байтов
дескрипторов внутри групп релевантности; точечные enum-исключения первыми.
Первая находка минимальна по числу правок в опубликованном пространстве.
Бюджет вызовов evaluate ограничен и назван в манифесте.

## lawref.amend.DEFAULT_BUDGET

*attribute* · *module attribute*

```python
DEFAULT_BUDGET = 600
```

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

## lawref.amend.DEFAULT_MAX_EDITS

*attribute* · *module attribute*

```python
DEFAULT_MAX_EDITS = 2
```

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

## lawref.amend.OPS_CAP

*attribute* · *module attribute*

```python
OPS_CAP = 64
```

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

## lawref.amend.SCHEMA_VERSION

*attribute* · *module attribute*

```python
SCHEMA_VERSION = 'law.amend/0.2'
```

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

## lawref.amend.amended_document

*function*

```python
def amended_document(document: dict, report: dict) -> dict | None
```

Документ с применённой найденной поправкой (для --apply).

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

## lawref.amend.apply_edits

*function*

```python
def apply_edits(document: dict, edits: list[dict]) -> dict | None
```

Применить набор операций; None — набор внутренне несовместим
(операция ссылается на снятый узел). Каскад remove_rule снимает и
priority_rule на него — повисших ссылок [§116](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/17-part-xvi-priority-declarations.ru.md#116-direct-priority) поправка не оставляет.

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

## lawref.amend.edit_space

*function*

```python
def edit_space(document: dict, targets: list[tuple[str, dict]], counter: list[int], budget: int, *, view=None, enum_ops: list[dict] | None = None) -> tuple[list[dict], bool, int]
```

(операции, было_ли_усечение, сколько релевантных).

Порядок — сначала операции над правилами, ПРИМЕНЁННЫМИ в proof-графах
целевых сценариев, затем остальные; внутри группы — сначала точечные
enum-исключения (DECISION-0178), затем канонические байты.
Кап OPS_CAP режет хвост, а не голову: до 03.09.2026 сортировка была
чисто канонической, и на акте в 2124 правила (kz-income-tax) нужная
операция в 64 первых не попадала — перебор сжигал бюджет на заведомо
чужих правилах и отвечал «не найдена, перебор усечён». Релевантность
читается с витрины движка (rule_application), детерминирована документом
и сценариями, семантики не добавляет.

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

## lawref.amend.render_text

*function*

```python
def render_text(report: dict) -> str
```

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

## lawref.amend.report_bytes

*function*

```python
def report_bytes(report: dict) -> bytes
```

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

## lawref.amend.synthesize

*function*

```python
def synthesize(document: dict, targets: list[tuple[str, dict]], regression: list[tuple[str, dict]], max_edits: int = DEFAULT_MAX_EDITS, budget: int = DEFAULT_BUDGET, goal_targets: tuple[list[dict], list[tuple[str, dict]]] | None = None, profile: dict | None = None) -> dict[str, Any]
```

Перебор; отчёт детерминирован кортежем (документ, цели, регресс,
max_edits, budget). targets — [(имя, {"case","query","expect"})],
regression — [(имя, {"case","query"})] формата О-1.

`goal_targets` (DECISION-0089 [§4.2](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/02-part-ii-goals-and-scope.ru.md#4-не-цели-01), `amend --goals`) — (понижённые
документы целей, миры формата О-1): целевой исход — всякая цель, павшая
на базовом документе (FAILED), держится (HELD) после поправки, и ни одна
цель не падает и не пропускается; цели HELD/VACUOUS до поправки —
сторожа, они входят в условие вместе с регрессом. Enum-исключения и
автоматические соседи (DECISION-0178) добываются из явных truth-целей;
goals-only не задаёт входа для такой подстановки. Свободный синтез правил,
скалярных условий и сочетаний нескольких осей остаётся вне пространства.

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