## Why Единая нормализация ББ/ОФР (RSHB/arm-ka-docs#116, change docs `unified-statement-normalization`, DBML v5.19, решения владельца 17–18.10.2026): строки формы хранятся как в источнике (повтор кода, строки без кода, `row_index`), шапка — сырым текстом с уверенностью, предупреждения и нарушения §7 — в `document_issue`, чтения «по коду» идут через агрегат, контракт распознавания получает `MAJOR` 2. Спека `arm-core` в docs разбита на две части поставки; этот change — **часть А**, не зависящая от пакета `arm_statements` (плана 1) и от мапперов результата `2.0`. Issue — RSHB/arm-core#126. ## What Changes Часть А закрывает требования спеки `arm-core` (таблица «Покрытие спеки» плана 3): - **Схема и миграция v5.19** (A1, A2): `data-model` — модели, миграция вверх с заполнением, откат с остановкой на несовместимых данных. - **Хранение формы и 1.x** (A9): `osv-result-mapping` — поля v5.19, `file_ordinal` у всех документов, вторая форма того же типа (Р-10, Р-18), `MAPPING_WARNING`, §7 при приёме `1.x`, полярность `needs_review`. - **Признак `origin`, агрегат по коду** (A7, A13): `statement-checks`, `osv-result-mapping`. - **Шапка `header_source`** (A1, A9, A8), **ответ `GET …/statement`** (A8), `issue_counts`, `DocumentOut.issues` — `documents-api`. - **PATCH формы** — строки, колонки, подтверждение, наименование организации; пересчёт после правки; порядок 409 подтверждения (A11–A13): `documents-api`. - **Условие `RECOGNIZED` 2.0 и статус ОСВ — чистые функции** (A10) и словарь имён с синонимами (A6). - **Очистка форм перед выкладкой** (A4): `primary-files`, скрипт `scripts/purge_statements.py`. - **`crm_id` ГСК/ГСЗ** (A3): `directories-api`. - **Приём конвертов обоих MAJOR, предупреждения файла структурами** (A5): `recognition-job-exchange`, `documents-api` (`JobBrief.warnings`). **Архивация (R-7).** Change заархивировать только вместе с `unified-normalization-core-b`; дельты содержат поведение части Б. ## Остаётся части Б (change `unified-normalization-core-b`) Мапперы результата `2.0` (B4, B5), переход на пакет `arm_statements` (пересчёт и §7 через точку входа пакета, `document_issue` видов `relation` / `soft` с `core`, относительные даты, удаление копии словаря §7, B1–B3, B6), `CHECKS_NOT_PASSED` из `document_issue`. До части Б §7 считается ядром на лету (P3-14); код временного пересчёта удаляется в B6. Требования спеки формулируются здесь целиком по docs; пункты, помеченные в таблице покрытия как часть Б, этот change не реализует. ## Capabilities ### New Capabilities ### Modified Capabilities - `data-model`: DBML v5.19, миграция. - `osv-result-mapping`: хранение формы, `file_ordinal`, `origin`, шапка, `RECOGNIZED` 2.0, формы `1.x`. - `documents-api`: `GET`/`PATCH` формы, `document_issue`, пересчёт, порядок 409, словари, предупреждения файла и ОСВ. - `primary-files`: очистка форм перед выкладкой. - `recognition-job-exchange`: конверты обоих MAJOR. - `directories-api`: `crm_id` ГСК/ГСЗ. - `statement-checks`: агрегат формы по коду, §7 по агрегату. ## Impact `api/src/models/**`, `api/alembic/versions/0007_*`, `api/src/services/{result_mapping,documents,statements,recognition_exchange,related_groups}.py`, `api/src/schemas/**`, `api/src/contract/**`, `api/contracts/**`, `api/rules/statement_lines.yaml`, `api/scripts/purge_statements.py`, `README.md` («Ошибки API»), `Makefile` (`DBML`). Выкладка: PR части А в `main` без снимка контура до части Б (O-9); `sync-web` — после плана 6. ## Non-goals Мапперы `2.0`, пакет `arm_statements`, фронт (arm-web), docs-worktree.