## Context Реализация — PR RSHB/arm-core#141 (ветка `add-preset-shahmatka`), задача AURORA-1747 (выделена из AURORA-1536 решением владельца 21.10.2026). Расчёт элиминации §5 — сумма по тройке с `elimination_mode` каскадом по `rule_no`, упаковка строк и «без пары», API списка пар, фиксация `elimination_rules_version` — остаётся в AURORA-1536 и в этот change не входит. Шахматка — чистая функция от сводной ОСВ версии, периметра и выбранных счетов; в БД не хранится (DECISION-5). Корректировки (`correction`) — хранимые ручные решения, читаются, но в ядре пока никем не создаются. ## Decisions 1. Режим PRESET берёт правило по `rule_id`. Правило должно быть действительно для версии: при зафиксированном `elimination_rules_version` — совпадать по `version_no`, иначе — иметь `valid_to IS NULL` и максимальный открытый `version_no`; иначе 404. 2. Сторона дебета — `company_1`, если `side_1 = D`, иначе `company_2`; кредит — вторая сторона. Счета и исключения раскрываются по иерархии (`_select_accounts`), как в MANUAL. Нет счетов хотя бы одной стороны — 422 `ACCOUNTS_REQUIRED`; неверные `side_1`/`measure`/`company_no` — 422 `INVALID_RULE`; не передан `rule_id` — 422 `RULE_REQUIRED`. 3. Показатель (`closing`/`turnover`) берётся из правила; ALL и MANUAL остаются на `closing`. 4. Применённые корректировки правила (`status = APPLIED`, тот же `rule_id` и версия консолидации) уменьшают `amount_a` ячейки `(A, B)` на `debit_adjustment` корректировки (`legal_entity_id = A`, `counterparty_id = B`) и `amount_b` на `credit_adjustment` корректировки `(B, A)`; расхождение, процент и порог пересчитываются, ID корректировок попадают в `correction_ids_debit/credit`. 5. `unpaired-osv` строится из `one_sided`-ячеек шахматки пресета (`osv_entry_ids_*`) и возвращает строки сводной ОСВ, содержащие эти записи. 6. `GET …/elimination-rules` отдаёт объект с основанием выбора версии; `as_of` не вводится. 7. xlsx пресета: имя `intercompany-matrix_<ГК>_<год>-<квартал>_v_rule-balance-.xlsx`, в шапке «Режим = Пресет», номер правила, статьи сторон, фактическая версия правил, коды счетов сторон (отсортированы) и строка «Показатель» (Сальдо/Оборот) для всех режимов. ## Решения владельца (2026-10-21, ревью PR #141) 1. **Фиксация версии правил — в AURORA-1536 (следующий шаг, не этот change).** Пока `consolidation_version.elimination_rules_version` пуст, шахматка берёт открытые правила (`valid_to IS NULL`); сейчас версия правил одна (`seed/core/elimination_rules_v1.yaml`, `valid_to` не задаётся, API управления правилами нет), поэтому результат не плавает. Фиксировать версию — при создании версии консолидации или при первом расчёте, но не в GET-запросе. 2. **Какая версия правил берётся — действующая на дату составления консолидации**, а не на отчётный период версии. Реализация — вместе с п. 1 в AURORA-1536. 3. **Корректировки из шахматки убираются** (решение 4 выше и `correction_ids_*` в ячейке). Причины: корректировки в ядре никто не создаёт (спринт корректировок), семантика ключа `(rule, A, B)` относительно ячейки (A, B) / (B, A) не утверждена, счета корректировки и `parent_correction_id` не учитывались; §6 описывает шахматку как суммы первички. Код корректировок выделен в ветку `AURORA-1747` и возвращается после решения по аналитике AURORA-1643 «Учитывание корректировок в шахматке». 4. **Ручка `…/preset/{rule_id}/unpaired-osv` убирается** (решение 5 выше). Причины: «без пары» по наличию строк (дефект AURORA-1651), ложные срабатывания при пересечении счетов сторон (76 в правиле № 6), нет ячейки и стороны строки, расхождение с «без пары» §5. Сценарий закрывают AURORA-1653 (строки ОСВ ячейки) и AURORA-1536 (строки без пары по упаковке §5). Код — в той же ветке `wip/shahmatka-corrections-unpaired`. 5. **Пресет = правило Прил. 3 — дополнение к пресетам §6** (наборы счетов), не замена. PRESET ограничивается правилами ББ (`statement_type = balance`): правил ОФР в seed нет, ОФР в §4 открыт. Правка §6 — в `../docs`. После выноса п. 3–4 автором соответствующие требования дельты `consolidated-osv` удаляются из change. ## Decisions made without discussion - 2026-10-21. Change пишет ревьюер в ветке автора по решению владельца. Обоснование: автор не оформила OpenSpec. Цена ошибки: автор переписывает change. - 2026-10-21. Спека описывает фактическое поведение PR; спорное вынесено в Known issues. Обоснование: домен решает автор и владелец, не ревьюер. Цена ошибки: после решения владельца спека меняется дельтой. - 2026-10-21. Поле `as_of` удалено из `EliminationRulesOut` как мёртвое: после правок по ревью всегда `None`, в main его не было, потребителей нет. Цена ошибки: если фронт ждал `as_of`, поле нужно вернуть. - 2026-10-21. При незаданной версии правил выбирается максимальный открытый `version_no`; он возвращается в ответе `elimination-rules`, чтобы фронт видел фактически применённую версию. - 2026-10-21. mypy: `measure` аннотирован `Measure` без `cast`; слишком длинная f-строка имени файла свода ОСВ (`consolidated_osv.py`) разбита на две без изменения результата (ruff E501). Цена ошибки: нулевая. - 2026-10-21. В MODIFIED-блоке требования про правила элиминации и аудит экспорта приведён полный текст; требование «XLSX шахматки» (ALL/MANUAL) не менялось, поведение PRESET описано отдельным ADDED-требованием.