Andrey Epifancev 248f8b0c74 openspec(#116): спека по ревью K-1…K-25 и решениям владельца Р-20…Р-22; решения S-26…S-52
- 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
2026-10-18 02:17:36 +04:00

4.9 KiB
Raw Blame History

ADDED Requirements

Requirement: Адаптер json ИС шага 1

scan-gateway SHALL оставить у себя обмен с ИС Сканирование (горячие папки, опрос, срок, склейку набора json в raw/{job_id}.json до нормализации, очистку папки) и адаптер «таблица table_structure[i] json → FormCandidate»; шаги 2–8 SHALL выполняться копией пакета arm_statements. Адаптер SHALL: создавать кандидата на каждую таблицу каждого успешного json; копировать шапку json (organization, inn, units, date) в шапку каждой своей таблицы как Cell (text = form_name, confidence ИС); передавать label.form_name таблицы как заголовок в evidence (тип — общим правилом шага 1 по словарю заголовков, statement_labels.yaml уходит в словарь пакета); строить плотную сетку по row_index и column_index ИС (пустые позиции — null), Cell.ref = row:<row_index>; locator = file:<имя json>;table:<i>. value у OCR-ячеек всегда null.

Scenario: Один json — ББ и ОФР

  • WHEN json aep_3.json содержит две таблицы — «Бухгалтерский баланс» и «Отчет о финансовых результатах» — под общей шапкой
  • THEN два кандидата с locator file:aep_3.json;table:0 и …;table:1, у каждого копия шапки json

Requirement: Ошибки набора json

Ошибочный json набора (parse_error, непустой error.code, корень не объект) при хотя бы одном успешном соседе SHALL давать предупреждение файла JSON_FAILED (error, locator = file:<имя json>, в message — код и сообщение ИС); все json ошибочны — конверт error с кодом первого. Исключение при разборе таблицы — предупреждение файла TABLE_PARSE_ERROR (error, locator = file:<имя json>;table:<i>; документа у таблицы нет), остальные таблицы разбираются; ни одной таблицы не разобрано — error RECOGNITION_FAILED.

Scenario: Таблица упала при разборе

  • WHEN разбор table:1 json aep_3.json бросил исключение, table:0 разобрана
  • THEN документ BALANCE из table:0; в metrics.warnings — TABLE_PARSE_ERROR уровня error с locator = "file:aep_3.json;table:1"; конверт needs_check; ядро не автоподтверждает документы файла

Scenario: Потерянный ОФР (решение № 28 среза 3a)

  • WHEN <job_id>.json успешен (ББ), а <job_id>_ofr.json вернул INVALID_DOCUMENT
  • THEN документ ББ получает свой статус; в metrics.warnings — JSON_FAILED уровня error; конверт needs_check; ядро не автоподтверждает документы файла

Requirement: Что уходит из шлюза

scan-gateway SHALL удалить api/rules/statement_lines.yaml и подстановку наименований по справочнику, срезание уверенности кода до 99 по справочнику, выбор редакции для имён (_choose_edition), пропуск строк с нечисловым и пустым кодом со счётчиками, правило «оставлена первая строка» при повторе кода, синтез шапки, правило «ячейки под колонкой нет → confidence = 0, не распознано», привязку is_recognized к confidence и правило «любое предупреждение → needs_check». Модули normalizer/ocr/text|dates|amounts переезжают в общие разборы пакета, layout|rows|header| document — в шаги 2–6 пакета; ocr_lookalikes.yaml — в словарь пакета.

Scenario: Строки без кода в aep_3

  • WHEN в aep_3.json строки «БАЛАНС» и «Выручка» имеют пустой код, а в колонке значения мусор 211(1 |
  • THEN строки попадают в результат со статусами (detail под строкой с кодом, missing в начале таблицы) и сырым текстом; счётчиков «строк без кода с суммами пропущено» нет