## Why Формы ББ/ОФР из Excel разбираются собственным конвейером tabular-parser (раскладка, отбор строк, значения, проверки §7, статус), отличным от конвейера scan-gateway; ядро не доверяет ни одному и пересчитывает результат по косвенным признакам (строки без кода молча теряются, повтор кода теряет сумму, предупреждения — плоские строки). Change `unified-statement-normalization` в arm-ka-docs (issue RSHB/arm-ka-docs#116, дизайн с решениями Р-1…Р-24) приводит оба сервиса к одной цепочке шагов 1–9: шаг 1 (кандидат в форму) пишет адаптер источника, шаги 2–8 выполняет общий пакет `arm_statements`, результат и конверт — контракт v2.0. Этот change переносит требования в tabular-parser; реализация — план 4 (`plans/2026-10-18-plan-4-tabular-parser.md` в docs), issue RSHB/arm-tabular-parser#54. ## What Changes - **statement-parsing:** - **MODIFIED** «Листы форм и их продолжения находятся по содержимому» — классификация ОСВ → форма → продолжение → прочее, слабое продолжение только сразу после листа формы, лист «прочее» даёт `SHEET_OTHER`; - **MODIFIED** «Шапка документа» — поля шапки блока как `Cell` с `confidence = 100` в границах блока, разбор текста — общим кодом; - **MODIFIED** «Склейка листов-продолжений и статус документа» — склейка до раскладки, `segment_breaks`, `CONTINUATION_TYPE_CONFLICT`, `SHEET_NOT_JOINED`; статус документа считает функция пакета; - **MODIFIED** «Словари форм, координаты, golden» — словари форм живут в пакете, координат в коде нет, golden и манифест; - **REMOVED** «Заголовок таблицы, колонка кодов и колонки-периоды определяются по тексту», «Строки с кодом и значения», «Соотношения §7 — данные, проверка по колонкам» — шаги 2–8 выполняет копия `arm_statements`; - **ADDED** «Адаптер Excel шага 1», «Ячейка Excel», «Строки без кода и неизвестные колонки в Excel», «Манифест ожиданий на реальных формах», «Статус книги». - **tabular-recognition-service:** **MODIFIED** «Результат по контракту» — файл результата и конверт v2.0, структурные `metrics.warnings`, `service.statements_version`, ack `processing` — `schema_version = "2.0"`, запрос остаётся 1.0. - **osv-parsing:** **MODIFIED** «Контрольные суммы определяют статус» (`status` листа и `warnings[]` с кодами `OSV_*` и `severity = info` в документе, строк `sheet=<имя> …` в `metrics.warnings` нет) и «Форматы, лимиты, время» (несоответствие `file_type` — предупреждение файла `FILE_TYPE_MISMATCH` `info`). Остальной разбор ОСВ не меняется. - **BREAKING** для потребителей: файл результата и конверт — MAJOR 2.0 (`line_code` nullable, структурные предупреждения, нет `checks.duplicate_line_codes`); слияние PR — только после выкладки ядра, принимающего 2.0. ## Impact - Код: `api/src/parser/statements/{cells,forms,header_cells,adapter,pipeline}.py` (новые), `grid.py`, `detect.py`, `book.py`, `readers/`, `osv.py`, `checks.py`, `osv_warnings.py`; `api/src/contract/**` (модели v2.0), `api/contracts/**` (копия схем v2.0), `api/src/core/worker.py`, `api/src/app.py`; удаляются `statements/{checks,columns,detect,header,lines,merge,statement}.py` и `api/rules/statement_{headers,periods,checks}.yaml`. - Копия пакета `api/arm_statements/` (раскладывает `sync-statements`) — не правится. - Тесты: манифест `api/tests/statements_manifest.yaml`; golden `fixtures/golden/expected_{osv,statement}_parse/**` (отдельный PR fixtures, arm-tabular-parser#54). - Спеки: `statement-parsing`, `tabular-recognition-service`, `osv-parsing`. Контракт — `docs/contracts/` v2.0.