2026-10-18 20:00:12 +04:00

6.5 KiB
Raw Blame History

Context

Сквозной дизайн — change docs unified-statement-normalization (design.md, specs/arm-core/spec.md, план plans/2026-10-18-plan-3-arm-core.md). Здесь — решения уровня ядра для части Б; решения части А — в openspec/changes/unified-normalization-core-a/design.md (D-1…, A1-1…A5-6, P3-1…P3-24). Схема данных — ../docs/model/data-model-v5.19.dbml; код части А уже в main.

Goals / Non-Goals

Goals и Non-goals — см. proposal.md.

Decisions

  • D-1. Единственная точка входа в пакет. import arm_statements — только api/src/services/statements_engine.py (протокол StatementsEngine и его реализация) и api/src/domain/stored_form.py; остальной код ядра работает с протоколом.
  • D-2. §7 хранится только как document_issue. GET …/statement и POST …/confirm читают нарушения из записей; временный расчёт на лету (P3-14 части А) удаляется в B6.
  • D-3. Архивация вместе с частью А (R-7 части А). unified-normalization-core-b архивируется только вместе с unified-normalization-core-a и только после выкладки обеих частей; сначала архивируется А, затем Б (дельты Б MODIFIED опираются на требования, которые А добавляет).
  • D-4. Дельта «копия словаря §7 ядра» оформлена как MODIFIED. Требования с таким именем в openspec/specs/ нет: упоминание копии живёт в «Соотношения §7 по колонкам»; поэтому удаление выражено правкой этого требования (и пунктом «Словари ядра» в documents-api), а не REMOVED.

Decisions made without discussion

Решения, принятые без обсуждения с человеком на этапе плана и исполнения части Б (маркеры P3-n — из плана 3, R-n — рулинги контроллера, Р-n — решения владельца). Таблица дополняется задачами B1–B6.

Дата Решение Обоснование Цена ошибки
2026-10-18 R-1 (Р-40). CODE_NOT_IN_DICTIONARY / CODE_NOT_IN_EDITION пишутся только для кодов из ровно четырёх цифр; пятизначные подстроки Excel не проверяются. P3-7 плана в этой части заменён (запись на код документа сохраняется, пятизначные коды — нет) решение владельца 18.10.2026 (Р-40) перед исполнением Б; закрывает O-3 (поток info у пятизначных) пропущенный info у нестандартного пятизначного кода; восстановление — снять условие длины кода в маппере 2.0 и пересчёте
2026-10-18 R-2 (Р-34). Подтверждение кода строки — флаг is_confirmed; line_code_confidence и line_code_modified не меняются (P3-16 части А) решение владельца 18.10.2026; в пересчёте Б правило is_confirmed ⇒ needs_review строки = false берётся из P3-16 нет — поведение уже реализовано в части А
2026-10-18 R-3. Удаление копии словаря §7 в дельте оформлено как MODIFIED «Соотношения §7 по колонкам», а не REMOVED (см. D-4); «Ответ GET …/statement» и порядок 409 оформлены новыми ADDED-требованиями, так как в openspec/specs/ и дельтах части А одноимённых нет openspec archive требует, чтобы имя REMOVED/MODIFIED существовало; иначе архив упадёт при архивации — правка имён заголовков дельт
2026-10-18 P3-25 (B1). Тип формы во входе пересчёта — document.document_type (BALANCE / INCOME / DISCLOSURE), а не meta.statement_type (только balance / income); план писал «тип формы» без источника DISCLOSURE не представим в statement_type; тип документа — единственный источник для всех трёх типов форма DISCLOSURE собралась бы с ошибкой KeyError / потерей типа; правка — одна строка в build_stored_form
2026-10-18 P3-26 (B1, O-3 часть А). Копия statement-code-orders.yaml в api/contracts/ не заводится: перечень кодов читает пакет из своей байтовой копии api/arm_statements/rules/statement_code_orders.yaml (loader._ORDERS), ядро файла не открывает; идентичность копии пакета с docs/contracts/statement-code-orders.yaml проверяет sync-statements --check; тест идентичности контракта сверяет только *.json. Сейчас копия пакета побайтно равна файлу docs второй экземпляр файла в ядре никто бы не читал и он мог бы разойтись с пакетом нет; если sync-statements когда-либо перестанет сверять YAML — добавить сверку в contract_identity.py
2026-10-18 P3-27 (B1). edition_codes берёт строки ok результата 2.0, сортирует по row_index и помечает код уверенным при line_code_confidence == 100 (ровно), None — неуверенный как в разделе «Что ядро вызывает» и в recompute пакета (код правленый/подтверждённый там — code_fixed) редакция приёма разойдётся с редакцией пересчёта; сверку делает test_edition_codes_and_engine_edition