diff --git a/openspec/changes/unified-statement-normalization/design.md b/openspec/changes/unified-statement-normalization/design.md index 4144053..1ba1359 100644 --- a/openspec/changes/unified-statement-normalization/design.md +++ b/openspec/changes/unified-statement-normalization/design.md @@ -1,7 +1,7 @@ # Единый алгоритм нормализации ББ/ОФР (scan-gateway и tabular-parser) — дизайн Issue: arm-ka-docs#116. Статус: черновик; текущая цепочка описана, целевая картина по шагам 1–9 — предложение, ждёт -решений владельца Р-5…Р-7; Р-1…Р-4 решены (brainstorming 17.10.2026). +решений владельца Р-6, Р-7; Р-1…Р-5 решены (brainstorming 17.10.2026). ## Цель @@ -520,7 +520,7 @@ line_name_confidence, values}`: `line_code` — разобранный код (4 статус конверта — агрегат. Предупреждение — структура `{code, severity: error | info, message, line_ref?, column_index?}`, а не строка. -- **1. Критерий `done`** — один критерий из самого результата: раскладка найдена ∧ (организация или ИНН) ∧ дата отчёта ∧ все строки `ok` ∧ нет значений `needs_review` (см. «Подтверждение проверкой» ниже) ∧ жёсткие проверки §7 сошлись ∧ нет предупреждений уровня `error`. `DISCLOSURE` — `done` без условий о раскладке, строках и проверках (как сейчас). Excel выполняет условия уверенности автоматически +- **1. Критерий `done`** — один критерий из самого результата: раскладка найдена ∧ (организация или ИНН) ∧ дата отчёта ∧ все строки `ok` ∧ нет значений и строк `needs_review` (см. «Подтверждение проверкой» ниже) ∧ жёсткие проверки §7 сошлись ∧ нет предупреждений уровня `error`. `DISCLOSURE` — `done` без условий о раскладке, строках и проверках (как сейчас). Excel выполняет условия уверенности автоматически - scan-gateway: «ничего не выброшено и уверенность 100» → общий критерий - tabular-parser: `_is_ok` → общий критерий; добавляются строки и значения - **2. Влияние предупреждений** — по уровню: `error` → `needs_check`, `info` — не влияет; у обоих одинаково; уровень каждого предупреждения задаётся в спеке (например, «строка заголовка не найдена», «колонка без даты», «тип по кодам противоречит заголовку» — `error`; «подпись из словаря исключений пропущена», «дробные при тыс. руб.» — `info`) @@ -539,7 +539,7 @@ column_index?}`, а не строка. **Подтверждение проверкой (вопрос владельца 17.10.2026).** Проверка §7 — арбитр, уверенность — подсказка там, где проверки нет. По каждому значению сервис считает `needs_review`: -- `true`, если `confidence` ниже порога (Р-5) **и** значение не покрыто сошедшимся жёстким соотношением §7 в своей +- `true`, если `confidence` ниже порога (Р-5: 100) **и** значение не покрыто сошедшимся жёстким соотношением §7 в своей колонке (не входит ни в одно, соотношение не сошлось или оно мягкое); для `is_recognized = false` — то же правило, если Р-7 = да, иначе всегда `true`; - `true` у всех ячеек соотношения в колонке, где оно не сошлось, независимо от уверенности; @@ -552,10 +552,18 @@ column_index?}`, а не строка. ошибки в одном соотношении; принимается (перекрёстные соотношения баланса его снижают). Закрывает AURORA-1524 без ущерба для 1519. Распространение на `is_recognized = false` — Р-7. +**Код и наименование строки (Р-5, решение владельца 17.10.2026).** Уверенность кода подтверждается не §7 (перепутанные +соседи 1220 и 1230 дают ту же сумму раздела), а структурой: код есть в перечне кодов формы и стоит по возрастанию +внутри раздела. Подтверждён — уверенность не важна; иначе `needs_review` у строки (`StatementLine.needs_review`), +документ — `needs_check`. По `fixtures/ocr` коды часто приходят с уверенностью 50 и 25, поэтому требовать 100, как +шлюз сейчас, нельзя. Перечень кодов форм без наименований — часть общего кода (нужен и для поиска столбца кодов), не +словарь строк. Уверенность наименования на статус и подсветку в сервисах не влияет: сервисы отдают текст как есть; +сопоставление файлового наименования со справочным по коду — вопрос ядра, открыт (см. «Что уходит из ядра»). + ### Шаг 9 — Результат Одинаково, как сейчас; контракт `recognition-result.schema.json` → **v1.3**: `line_status`, `line_code` nullable, -`line_code_text`; `needs_review` у значения; `document.status`; `document.warnings[]` и `metrics.warnings[]` +`line_code_text`; `needs_review` у значения и у строки; `document.status`; `document.warnings[]` и `metrics.warnings[]` структурные (уровень, привязка); `checks` обязателен для `BALANCE` / `INCOME` со строками у обоих конвейеров (у документа без строк отсутствует), нарушения с кодами слагаемых, без `duplicate_line_codes`. @@ -576,7 +584,10 @@ column_index?}`, а не строка. - Достройка шаблонных строк: по словарю ядра; строки `missing` / `unreadable` показываются как пришли, с подсветкой; код, у которого есть хотя бы одна строка из файла, шаблоном не достраивается. - Экран: подсветка ячеек только по `needs_review` (уверенность, `is_recognized` и нарушения §7 уже сведены сервисом); - строк — по `line_status`; предупреждения документа — с привязкой к месту. + строк — по `line_status` и `needs_review` строки; предупреждения документа — с привязкой к месту. +- Открытый вопрос ядра (не сервисов): сопоставлять ли файловое наименование строки со справочным по коду и что + делать при расхождении (владелец 17.10.2026: «наверное, будем пытаться сопоставить»). В сервисах уверенность и + текст наименования на статус не влияют. ### Решения, которые нужны от владельца @@ -598,9 +609,12 @@ column_index?}`, а не строка. - **Р-4** (шаг 3, п. 3) — **решено владельцем 17.10.2026:** повторы кодов законны; все строки сохраняются и показываются, для проверок и всех операций после подтверждения или автоподтверждения — суммой по коду. Следствие: снять уникальность `(meta_id, line_code)` в DBML. -- **Р-5** (шаг 8, «Подтверждение проверкой») — порог уверенности, ниже которого значение попадает в `needs_review`, - если не подтверждено проверкой §7 (= решение № 7 по спринту 2, AURORA-1519 / 1524); предложение — 100, как сейчас: - ложных подсветок станет меньше за счёт подтверждения проверкой, а не за счёт порога. +- **Р-5** (шаг 8, «Подтверждение проверкой») — **решено владельцем 17.10.2026:** порог для значений — 100 (у ИС + уверенность дискретная: 100, ~80, 71, 67, 60, 50, 25, 0, промежутка 90–99 нет; в группе 70–89 есть настоящие ошибки, + например «11 30» с уверенностью 80); ложных подсветок становится меньше за счёт подтверждения проверкой §7, а не + порога. Код строки подтверждается структурой (перечень кодов формы + порядок), не уверенностью. Уверенность + наименования в сервисах не используется; сопоставление со справочным — открытый вопрос ядра (= решение № 7 по + спринту 2, AURORA-1519 / 1524). - **Р-6** (шаг 2, п. 6) — неизвестная числовая колонка без периода: оставлять без даты с предупреждением (`needs_check`) или пропускать, как парсер сейчас. - **Р-7** (шаг 8, «Подтверждение проверкой») — снимать ли подсветку сошедшимся соотношением §7 и с `is_recognized =