## ADDED Requirements ### Requirement: Адаптер Excel шага 1 tabular-parser SHALL оставить у себя чтение книги (лимиты `PARSE_MAX_BYTES`, `PARSE_TIMEOUT_SECONDS`, формат по сигнатуре, лимиты zip и объединённых ячеек, `UNREADABLE`), классификацию листов (ОСВ — отдельный путь; форма; продолжение; прочее) и адаптер «блок формы на листе → `FormCandidate`» общего кода; шаги 2–8 по формам SHALL выполняться копией пакета `arm_statements`. Адаптер SHALL: выделять блоки форм на листе по заголовку или ОКУД (без кодов между ними блоки сливаются, заголовок после кодов — новая форма); собирать шапку каждого блока в его границах (организация, ИНН без ИНН аудитора, ОКПО, ОКОПФ, ОКФС, единицы, дата, адрес) как `Cell` с `confidence = 100`; заполнять у каждой ячейки `text` по числовому формату (tp#42) и `value`, `ref = <лист>!`; дописывать листы-продолжения в сетку открытой формы до раскладки (маркер «Форма … с.2» или позиция листа; проверки типа, диапазона кодов и, при трёх и более кодах, числа колонок — как `join_blocker`), записывая границы листов в `segment_breaks`. Несовпадение формата с `file_type` — предупреждение файла `FILE_TYPE_MISMATCH` (`info`). #### Scenario: Книга ББ + ОФР - **WHEN** книга содержит лист «Баланс» (ОКУД 0710001), лист «Баланс (2)» с маркером «Форма 0710001 с.2» и лист «ОФР» - **THEN** адаптер выдаёт два кандидата: `BALANCE` с `locator = sheet:Баланс,Баланс (2)` и одной сеткой из двух листов (`segment_breaks` — первая строка второго листа) и `INCOME` с `locator = sheet:ОФР` #### Scenario: Ссылки ячеек - **WHEN** код строки стоит в ячейке C27 листа «Баланс» - **THEN** `ref` строки — `Баланс!C27` ### Requirement: Строки без кода и неизвестные колонки в Excel tabular-parser SHALL отдавать строки без кода с содержимым со статусами `detail` / `missing` / `unreadable` (Р-8; ранее не отдавались, OQ-36 / OQ-141), числовые колонки с нераспознанной подписью — колонкой без даты и `error` (ранее пропускались), повторы кодов — всеми строками без `duplicate_line_codes`. #### Scenario: НПЗ «Реализация иного имущества» - **WHEN** в ОФР ФСБУ 4/2023 строка «Реализация иного имущества…» без кода с суммами стоит под строкой 2340 - **THEN** в результате строка `detail` с `parent_ref` строки 2340; ранее она отбрасывалась со счётчиком ### Requirement: Путь ОСВ в контракте v2.0 У `osvDocument` tabular-parser SHALL выдавать `status` (`done`, когда ведомость разобрана, иначе `needs_check` — по прежним условиям §1.6 листа) и `warnings[]` — прежние предупреждения листа структурами с `severity = info` и кодом с префиксом `OSV_`; строк вида `sheet=<имя> <текст>` в `metrics.warnings` больше нет. Остальной разбор ОСВ не меняется. #### Scenario: Предупреждение ОСВ - **WHEN** на листе ОСВ есть строка без родителя - **THEN** у документа ОСВ предупреждение `{code: "OSV_…", severity: "info", message}`, статус документа по §1.6 ### Requirement: Статус книги Статус конверта tabular-parser SHALL вычисляться по общему правилу: `done` ⇔ все документы `done` ∧ нет предупреждений файла уровня `error`; книга без листов ОСВ и форм — `error INVALID_DOCUMENT`. Порядок документов — сначала ОСВ в порядке листов, затем формы. #### Scenario: Книга только из пояснений - **WHEN** книга содержит только листы пояснений (0710003, «Пояснения») - **THEN** документы `DISCLOSURE` со статусом `done`, конверт `done`