docs(#116): дизайн единой нормализации ББ/ОФР (scan-gateway + tabular-parser) #117

Merged
aep merged 63 commits from feat/116-unified-normalization into main 2026-10-18 18:43:08 +03:00
Owner

Closes part of #116: дизайн единого алгоритма нормализации результата распознавания ББ/ОФР для scan-gateway и tabular-parser.

Что в PR:

  • openspec/changes/unified-statement-normalization/design.md — текущая цепочка шагов 0–9 с таблицами различий и целевая картина (единый выход каждого шага, решения по каждой строке различий), решения владельца Р-1…Р-19, «Decisions made without discussion» 1–23.
  • Пять отчётов независимого ревью (review-2026-10-17*.md): F-1…F-25, V-1…V-13, G-1…G-30, W-1…W-16, H-1…H-26 — все находки внесены в дизайн.

Следующий шаг (отдельными PR): спека — дельты OpenSpec, контракт v2.0, §11/§12 в 05-domain-rules.md, DBML v5.19.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W

Closes part of #116: дизайн единого алгоритма нормализации результата распознавания ББ/ОФР для scan-gateway и tabular-parser. Что в PR: - `openspec/changes/unified-statement-normalization/design.md` — текущая цепочка шагов 0–9 с таблицами различий и целевая картина (единый выход каждого шага, решения по каждой строке различий), решения владельца Р-1…Р-19, «Decisions made without discussion» 1–23. - Пять отчётов независимого ревью (`review-2026-10-17*.md`): F-1…F-25, V-1…V-13, G-1…G-30, W-1…W-16, H-1…H-26 — все находки внесены в дизайн. Следующий шаг (отдельными PR): спека — дельты OpenSpec, контракт v2.0, §11/§12 в `05-domain-rules.md`, DBML v5.19. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 22 commits 2026-10-17 20:38:19 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 5 commits 2026-10-17 23:54:22 +03:00
- proposal: зачем, что меняется, порядок выкладки «сначала ядро», non-goals
- statement-normalization: шаги 1–8 общего кода arm_statements (кандидат, раскладка, статусы строк,
  значения, §7, needs_review, структурная проверка кода, уровни предупреждений, статус)
- recognition-contract: файл результата и конверт v2.0, переход 1.x → 2.0
- tabular-recognition-service, scan-gateway: адаптеры шага 1 и что уходит из сервисов
- arm-core: хранение v2.0, агрегат по коду, document_issue, RECOGNIZED, PATCH lines/columns/confirmed,
  порядок 409, миграция v5.19, crm_id ГСК/ГСЗ
- arm-web: экран проверки формы по новым полям
- design.md: автозамена между файлами — §9.5 п. 3, а не §12 п. 3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- recognition-result.schema.json 2.0: line_code nullable + line_status, row_index, ref, parent_ref,
  line_code_text, needs_review у значения и строки, values[].text, <поле>_text/_confidence шапки,
  needs_review_fields, period_kind, label_confidence, document.status/warnings у всех документов
  (включая ОСВ), form_variant, checks обязателен у ББ/ОФР со строками, нарушения с codes, без
  duplicate_line_codes, service.statements_version; changelog — в $comment
- recognition-result-message.schema.json 2.0: metrics.warnings — структуры
- примеры переведены на 2.0 (Excel: detail-строка и нарушение пустой цели; OCR: догадка, покрытая §7,
  строка unreadable, разлепленная строка)
- 03-architecture: общий код arm-statements, контракт v2.0
- спека: у разлепленных строк line_code_text и text — k-е части

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- 05-domain-rules: §11 объединяет прежние §11, §11.1 и §12 (источники OCR и Excel, шаги 2–8, таблица
  уровней предупреждений, что отменено); §12 — заголовок-ссылка; §7 — общий словарь у сервисов,
  «посчитанное» соотношение, abs_terms подтверждают величину, упрощённый набор; §9.3 — RECOGNIZED при
  приёме v2.0; §9.5 — хранение v2.0, агрегат по коду, 409 LINES_UNRESOLVED / DUPLICATE_FORM, PATCH
  lines/columns/confirmed; §1.6 — статус и предупреждения ОСВ в v2.0
- отменены: OQ-36/OQ-141 (Р-8), решение № 22 среза 3a (Р-11), решение 08.10.2026 по OQ-156 (Р-17);
  решение № 30 сохранено для OCR-текста
- 07-open-questions: закрыты OQ-36, OQ-141, OQ-147, OQ-152; OQ-156 пересмотрен; OQ-148 — допущение
  спеки; примечания к OQ-33, 145, 146, 149, 150; новые OQ-165 (склейка половин формы, Р-15),
  OQ-166 (упрощённая форма), OQ-167 (несколько периодов в файле ИС)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- financial_statement_line: снята уникальность (meta_id, line_code); row_index, source_ref (частичный
  уникальный индекс), line_status (enum statement_line_status), line_code_text, parent_row_index,
  needs_review, is_confirmed
- financial_statement_value: source_text, needs_review (хранится — пересмотр п. 4 v5.13), is_confirmed,
  confirmed_by/at; financial_statement_column: period_kind, label_confidence;
  financial_statement_meta: form_variant (enum statement_form_variant), needs_review_fields
- новая таблица document_issue + enum document_issue_kind, issue_severity, issue_source
- recognition_job.statements_version; document: file_ordinal, уникальность типа на файл — только не для
  BALANCE/INCOME (Р-10); related_group.crm_id (arm-core#112)
- changelog и правила заполнения миграции в шапке; entities-v5.19.md; диаграммы части 01, 04, 06
  (document_issue — в части 06); ссылки на текущую модель и DBML в Makefile — v5.19

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- §5.6.1: новые поля StatementOut (статусы строк, повторы кода, reference_name, needs_review, text,
  issues[], period_kind, form_variant), PATCH values[].confirmed / columns / lines, порядок 409
  подтверждения с LINES_UNRESOLVED и DUPLICATE_FORM, crm_id ГСК/ГСЗ
- §9: новые коды ошибок с пометкой «после #116»; §11: строка о предстоящем изменении

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-17 23:55:07 +03:00
Раздел «Решения при написании спеки (18.10.2026)» в Decisions made without discussion: значения, которые
дизайн оставлял спеке (порог сходства наименований, формулы упрощённого набора, словари подписей, коды
предупреждений, period_kind, имена DBML), и уточнения (ожидаемые даты колонок, квартал периода в RECOGNIZED).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-18 00:43:04 +03:00
aep added 5 commits 2026-10-18 01:17:48 +03:00
- recognition-result.v1.schema.json и recognition-result-message.v1.schema.json — байтовые копии схем 1.2 / 1.0
  (до 9b1a4cc), примеры 1.x — examples/v1/; живут до удаления маппера 1.x ядра (K-8)
- statement-code-orders.yaml — упорядоченные перечни кодов ББ/ОФР по редакциям 66n / fsbu4 и вариантам
  full / simplified, с законными повторами (Р-20: 1220, 1520, 2410 у fsbu4; раздел III НКО у 66n) и кодами
  печатных форм 1С из fixtures (1105, 1130, 1140, 1215, 1231, 1530, 2420, 2460, 2530, 2930) (K-5)
- validate_contracts.py: схемы v1 и examples/v1/, проверка формы перечня кодов; make venv ставит PyYAML
- v2.0: header.okei (+ _text, _confidence) и okei в headerField (K-22); columns[].column_index — столбец сетки
  кандидата (K-6); line_refs — только строки lines[]; ref Excel — имя листа в кавычках по правилу Excel (S-15);
  статус ОСВ — по контрольным суммам §1.4 листа (S-22); примеры приведены к этим правилам

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- financial_statement_line: «создана правкой» ⇔ row_index IS NULL; line_code_original_value — код из результата,
  правками не меняется (K-1)
- financial_statement_meta: header_source (jsonb — <поле>_text и <поле>_confidence всех полей шапки),
  organization_name_original_value, organization_name_modified (K-3, K-12)
- document_issue: codes (коды нарушения §7), column_index (столбец вне колонок формы); code у relation / soft —
  RELATION_FAILED / RELATION_SOFT; line_ids очищаются при удалении шаблонной строки (K-6, K-13, S-19)
- заполнение при миграции: row_index = NULL у строк правки, document_issue — §7 копией arm_statements (K-2);
  откат — только на пустой или совместимой с v5.18 БД (K-19)
- entities-v5.19, диаграмма part06 перерисована

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- §7: мягкое соотношение, сошедшееся точно, подтверждает неуверенные значения (Р-21); ОФР упрощённого набора
  2400 — мягкое (Р-22 / S-5); form_variant = null — полный набор; 1.x и мигрированные формы — §7 копией
  arm_statements один раз в document_issue, экран и подтверждение читают только его (K-2)
- §9.3: страховка согласованности document.status = done (K-24), «того же периода» — год и квартал (K-20),
  1.x после правки — общим кодом (K-21)
- §9.5: признак строки правки — row_index IS NULL (K-1); header_source, codes/column_index document_issue (K-3, K-13);
  LINES_UNRESOLVED — сумма или текст (K-16); PATCH: organization_name (K-12), confirmed: false, line_status только
  detail, обратного detail нет, дата колонки обязательна, акцепт сбрасывает только правка данных, подтверждение даты
  отчёта тем же значением (K-17, K-23); 409 LINE_EXISTS → LINE_CODE_TAKEN (K-18)
- §11: TABLE_PARSE_ERROR и SHEET_OTHER — уровня файла (K-7); столбец кодов ищется всегда, DISCLOSURE с кодами ББ/ОФР —
  TYPE_CONFLICT (K-10); номер колонки (K-6); содержимое строки (K-14); нумерация с двойниками и одним пропуском (S-13);
  ref Excel с кавычками (S-15); единицы по словарю и ОКЕИ (K-22); перечень кодов — данные, законные повторы (K-5, Р-20),
  обе редакции всегда; синонимы и «итого по разделу» в сверке имён (S-4); интерфейс функции статуса (K-14); ожидание на
  реальных сканах (K-4); бланк 66н с относительными подписями (K-17)
- 07-open-questions: OQ-148 закрыт (Р-22 / S-7), OQ-166 уточнён, OQ-168 — коды перечня без образца
- dev/checks.md: копия arm_statements, sync-statements (коды 0 / 10 / 20 / 2), statements-check в check-full,
  проверки docs (K-9); frontend-api-guide §5.6.1 по новым правилам

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- DBML и §9.5 п. 2: inn_original_value = inn, report_date_original_value = report_date_text, units_original_value =
  units_text; сырой текст и уверенность всех полей — header_source (K-3)
- 03-architecture: путь копии, VERSION, коды sync-statements --check, перечень кодов в contracts/ (K-9, K-5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
- design.md: Р-20 (законные повторы кода в перечне, синонимы в словаре имён), Р-21 (мягкое соотношение, сошедшееся
  точно, подтверждает неуверенное значение), Р-22 (S-1…S-25 приняты с оговорками; отмечены утверждённые владельцем);
  решения при доработке S-26…S-52 с ценой ошибки
- statement-normalization: отдельное требование sync-statements (пути, VERSION, коды 0 / 10 / 20 / 2), словарь
  единиц и ОКЕИ, ref Excel с кавычками, нумерация с двойниками и пропуском, номер колонки, содержимое строки, столбец
  кодов у DISCLOSURE, упрощённый 2400 мягкий, Р-20 / Р-21 со сценариями, обе редакции перечня, интерфейс функции
  статуса, TABLE_PARSE_ERROR / SHEET_OTHER уровня файла
- arm-core: признак строки правки row_index IS NULL, header_source, формы без checks (1.x и миграция) — §7 ядром в
  document_issue, codes / column_index, RESULT_STATUS_INCONSISTENT, синонимы и «итого по разделу», PATCH
  organization_name / confirmed: false / подтверждение даты, LINE_CODE_TAKEN, акцепт и подтверждения, LINES_UNRESOLVED
  с текстом, «того же периода», откат миграции
- recognition-contract: MODIFIED «Копия контракта … идентична» — сверка по MAJOR копии, *.v1.schema.json на окне;
  1.x — MAPPING_WARNING / LEGACY_WARNING; okei, column_index, пустые массивы DISCLOSURE, статус ОСВ одной формулировкой
- quality-checks (новая дельта): make check охватывает копию arm_statements, make check-full — statements-check
- tabular-recognition-service: манифест statements_manifest.yaml — failed_relations страниц 2 баланса (K-25)
- scan-gateway, arm-web: TABLE_PARSE_ERROR файла; подсказки шапки, снятие подтверждений, LINE_CODE_TAKEN
- proposal: шаг 0 выкладки, перечни кодов, ожидания на реальных сканах, Impact

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-18 01:38:30 +03:00
aep added 4 commits 2026-10-18 10:36:17 +03:00
aep added 1 commit 2026-10-18 10:41:02 +03:00
aep added 1 commit 2026-10-18 10:53:16 +03:00
aep added 1 commit 2026-10-18 11:03:58 +03:00
Две части — два PR в RSHB/arm-core: часть А (A0–A13) не зависит от пакета
arm_statements, часть Б (B0–B6) — после плана 2; интерфейс-заглушка пакета,
решения P3-1…P3-18, открытые вопросы O-1…O-10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-18 11:11:19 +03:00
19 задач: каркас и make check, типы и сериализация, словари и загрузчик, разборы текста/кода/дат/сумм, шапка,
шаги 2–8, функция статуса, конвейер кандидата, точка входа пересчёта, golden на обезличенных входах aep_3, 1С и НПЗ.
Решения автора плана P1-1…P1-20, открытые вопросы O-1…O-4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-18 11:12:02 +03:00
aep added 1 commit 2026-10-18 11:16:28 +03:00
aep added 1 commit 2026-10-18 11:29:08 +03:00
Скрипт docs/scripts/sync-statements.sh (--check 0/10/20/2, --in-place, --dry-run, обычный режим
с worktree/issue/PR), помощник statements_check.py, тест на синтетических репозиториях; три
bounded PR подключения копии в arm-core, tabular-parser, scan-gateway. Решения P2-1…P2-21,
открытые O-1…O-4; закрыты O-1…O-4 плана 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-18 11:30:40 +03:00
aep added 1 commit 2026-10-18 11:32:17 +03:00
aep added 1 commit 2026-10-18 11:32:59 +03:00
aep added 1 commit 2026-10-18 11:33:17 +03:00
aep added 1 commit 2026-10-18 11:34:24 +03:00
aep added 3 commits 2026-10-18 11:56:15 +03:00
choose_edition, status_input / status_input_from_contract, to_contract / warning_to_contract,
code_column, amount_columns, normalize_label / normalize_caption, is_continuation, WarningCode,
StatementHeader.form_name, FailedRelation.expected/actual — Decimal | None, явные типы Rules.*,
min_codes_continuation в словаре; новая задача 19 (форма контракта), golden — задача 20;
P1-21…P1-31. Код XLS_NO_CODEPAGE (info, файл) — в таблицу спеки «Шаг 8 — предупреждения» и §11.9.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
tabular-parser: столбец кодов и колонки сумм — code_column / amount_columns пакета, метки —
normalize_label / normalize_caption, маркер — is_continuation, контракт — to_contract /
warning_to_contract (statements/contract.py не пишется), XLS_NO_CODEPAGE — предупреждение файла
вместо OSV_XLS_NO_CODEPAGE; scan-gateway: contract_map.py не пишется, form_name из пакета,
WarningCode в make_warning, FailedRelation.expected/actual — Money | None. Закрыты O-1…O-7, O-9
плана 4 и O-2…O-7 плана 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 2 commits 2026-10-18 12:03:21 +03:00
Пакет: engine.edition (choose_edition) и engine.contract_document_status
(status_input_from_contract) вместо сборки StoredForm ради редакции и status_input_from_v2;
FailedRelation.expected/actual — Decimal | None; O-8 закрыт.
API для плана 6: LineOut.line_code_confidence, StatementHeaderOut.okei, header.source.confidence —
строка Decimal, StatementOut.edition_lines, DocumentBrief.issue_counts, line_id/line_code в detail
ошибок элемента lines[]; P3-19…P3-24; спека arm-core и гайд §5.6.1 дополнены.
Р-34: подтверждение кода не меняет уверенность — буква спеки arm-core, §9.5 п. 9 и гайда приведена;
O-2 закрыт. Р-35: очистка отказывает только при верифицированной версии — P3-12, тесты A4, спека
«Очистка форм» п. 2 и сценарий; O-5 закрыт.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
line_code_confidence и okei в типах, header.source.confidence — строка, подсказка кода из
StatementOut.edition_lines, ошибка элемента lines[] у поля строки по detail.line_id
(lineErrorTarget вместо codeTakenKeys), значок документа в панели файлов по
DocumentBrief.issue_counts (rowBadge). Закрыты O-1…O-6, снят В-2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
aep added 1 commit 2026-10-18 12:04:44 +03:00
aep added 1 commit 2026-10-18 12:20:13 +03:00
aep added 1 commit 2026-10-18 13:15:22 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep added 1 commit 2026-10-18 15:01:55 +03:00
aep added 1 commit 2026-10-18 18:26:09 +03:00
aep added 1 commit 2026-10-18 18:33:20 +03:00
aep added 1 commit 2026-10-18 18:42:26 +03:00
aep merged commit 3fe7ad46ce into main 2026-10-18 18:43:08 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/arm-ka-docs#117
No description provided.