Хук в _map_candidate (result_mapping.py): после map_file, до auto_confirm — для
каждого документа BALANCE/INCOME/OSV строит снимок build_intake_payload и пишет
quality_intake_fact через insert_intake_fact. Чисто добавочный шаг: не меняет
документы, статусы и прочий результат маппинга; DISCLOSURE/OTHER факта не получают.
Счётчики строк/значений — из financial_statement_* (BALANCE/INCOME) и document_issue;
warning_count/osv_warnings — предупреждения источника service (document_issue.source =
service): для BALANCE/ОФР 1.x таких записей нет, для ОСВ это коды OSV_*. Для ОСВ
построчные счётчики не считаются (их в ядре нет), только row_count в payload.
Тесты в test_result_mapping.py (маркер integration, не запускались — нет PostgreSQL
в песочнице, подтверждена только коллекция) + один DB-free тест на множество типов
документов хука.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
attach_corrections молча пропускала (continue) корректировку, чей
агрегат (rule_id, пара ЮЛ) больше не существует после пересчёта
разнесения ВГО — вместо этого, как и в остальных ветках функции,
поднимаем ConflictError("CORRECTION_REVIEW_REQUIRED").
Кандидаты «Требуется проверка» / «Распознан» и состояние файлов («Обработка» / «Ошибка загрузки») чек-лист берёт
только со стола консолидации (§9.5 п. 11) — тем же фильтром, что панель «Первичные документы» (`files.on_desk`).
Документы организации из других консолидаций и из карточки ЮЛ ячейку больше не меняют: без документов — «Отсутствует».
В `on_desk` документ подзапроса — псевдоним: в запросе по `Document` он иначе коррелирует с внешним.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Пара «новый документ — прежний» с counterparty_check = MISMATCH у любого из двух
в автозамене не участвует: сканы разных организаций в одной карточке больше не
вытесняют друг друга. UNKNOWN заменяется как прежде. Если файл оставлен только
из-за MISMATCH, в mapping_warnings нового файла — «автозамена не выполнена»
с именем и версией оставленного файла. Спека primary-files дополнена.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- суммы сторон со знаком, как в шахматке; строки с суммой < 0 в упаковку не идут, причина NEGATIVE_AMOUNT;
при min(ΣA, ΣB) ≤ 0 процент null и элиминация 0, статус списка AUTO — только при элиминации > 0
- группы одного размера выбираются по проценту расхождения к меньшей сумме (точной дробью), ничья — по равному проценту
- elimination_amount группы и тройки переименован в deviation_amount; version_no тройки обязателен
- суммы и проценты пар в JSON — с двумя знаками
- elimination-pairs по правилу с measure ≠ closing — 422 INVALID_RULE
- дельта спеки, design.md (R-7, R-8), tasks, README
make check-full: exit 0 (1896 passed; integration 990 passed).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- consolidation_version.elimination_rules_version NOT NULL: миграция 0010
проставляет существующим версиям номер правил, действовавших на дату
создания (по Москве), иначе последних открытых; без правил — отказ;
создание версии без действующих правил — 409 ELIMINATION_RULES_MISSING;
ветки «правила не зафиксированы» убраны (rules, preset, is_version_fixed
всегда true);
- GET …/elimination-totals: все тройки «правило ББ × упорядоченная пара
периметра» с ΣA, ΣB, расхождением, суммой элиминации, статусом
AUTO/DISCREPANCY/ONE_SIDED/MANUAL и osv_entry_ids; сводная ОСВ строится
один раз; сбор строк сторон вынесен в _collect_rule_sides — общий
с упаковкой тройки.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Конфликты с #141: в ALL оставлены и фильтр забалансовых, и MatrixSelection; тесты
#141 на старый one_sided переписаны под расчёт по суммам.
- one_sided = ровно одна сумма нулевая (знак не важен), тесты с отрицательными суммами;
- шапка xlsx режима ALL — «Все балансовые счета»;
- фильтр GET /directories/accounts убран из PR (решение владельца 22.10.2026).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- маршрут result-table/export в EXPECTED_ROUTES, ruff format
- общие VersionExportInfo, _write_details, _group_name, _xlsx_response вместо копий шапки и ответа
- сумма компании в книге без молчаливого 0 (KeyError при пропуске в расчёте)
- своё описание 422 у маршрутов результирующей таблицы в OpenAPI
- тесты: 422 RESULT_ACCOUNTS_MISSING для экспорта без события EXPORT, схема OpenAPI экспорта
- требование перенесено из openspec/specs в change intercompany-result-table-export (+ audit-trail), README
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
I-2: NULL у is_recognized не сомнение (P3-54); I-3: metrics.file_warnings при приёме 2.0 — единый
источник для пересчёта (P3-53, R-11); I-4/T4.4/T6.1: тесты правки, акцепта и веток приёма 2.0;
T4.2: now в checks_on_intake_1x; M-4: row_by_ref по принятым строкам; документация (M-5, M-6, M-7).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Приём файла результата выбирает модель по MAJOR (parse_result); нечитаемый JSON и неизвестный
MAJOR — неповторяемая ошибка схемы (T5.2). Статус ОСВ 2.0 — osv_status_v2, предупреждения листа
(OSV_*) — в document_issue. Решения P3-46…P3-49.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T2.1: аудит lines[] включает итоговую смену parent_row_index после пересчёта.
T1.1: тест паритета редакции приёма и пересчёта для строки с confidence < 100 и code_fixed.
T1.2: edition_codes пропускает строку ok без кода.
T2.4: общий issue_column_index для ответа формы и detail отказа подтверждения.
T2.6: удалено дублирование needs_review в statement_line_edits.
T2.8: неизвестный relative:* не даёт 500 (адаптер stored_form и _resolve_relative_columns).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>