AURORA-1734/1735: уточнения по финальному ревью — сдвинутое значение и XLSB_NO_FORMATS в частях

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-11-07 09:10:38 +04:00
parent c509c5ed76
commit 6484cd67d0
3 changed files with 20 additions and 11 deletions

View File

@ -1695,7 +1695,7 @@ file:<имя json>;table:<i>`; документа у такой таблицы
одной формы и другой, чем у текущей части (тип части — по большинству кодов её первого сегмента с кодами), начинает
новую часть. Часть — обычный кандидат со своими колонками и периодами; первая сохраняет `locator`, `type_hint`,
`evidence` и предупреждения адаптера, следующие — `locator` `<исходный>;form:<k>`, без `type_hint` (тип только по
кодам, без `TYPE_CONFLICT`). Сегменты без шапки, с меньшим числом кодов или той же формы (повторная шапка второй
кодам, без `TYPE_CONFLICT`), из предупреждений адаптера — только `XLSB_NO_FORMATS`. Сегменты без шапки, с меньшим числом кодов или той же формы (повторная шапка второй
страницы ББ, раздел 25xx после ОФР) не режут; строки другой формы, приклеенные к сегменту без своей шапки, тоже.
Разрез — функция пакета `split_by_form`, хост вызывает её перед разбором каждой таблицы или листа; документы частей
различаются `file_ordinal` (Р-10), модель и контракт не меняются.
@ -1768,7 +1768,8 @@ file:<имя json>;table:<i>`; документа у такой таблицы
«За I полугодие 2025 года» разорвана на «31» и «а I полугодие 2025 года», под «31» — постороннее «$301» в строке 2400):
столбец с текстом подписи, не разобранным ни как период, ни как исключение, стоящий **между** колонками периодов
(есть левее и правее), с числом не более чем в одной строке с кодом при трёх и более у каждой колонки периода
сегмента, колонкой сумм не считается — его числа идут в то же `NUMBERS_OUTSIDE_TABLE` (`info`) с текстом «числа вне
сегмента и с числами всех колонок периода в строке его числа (число лишнее, а не сдвинутое из пустой ячейки периода),
колонкой сумм не считается — его числа идут в то же `NUMBERS_OUTSIDE_TABLE` (`info`) с текстом «числа вне
колонок формы не учитываются: …» (если среди адресов есть такой столбец; иначе прежний текст «правее таблицы»).
Столбец с числами в двух и более строках с кодом остаётся колонкой с `COLUMN_WITHOUT_DATE`.
7. **Столбец наименования** — подпись, начинающаяся с «наименование», в строке заголовка; иначе столбец левее кода с

View File

@ -35,14 +35,14 @@
| 2026-11-06 | Реальные JSON АК-ЮЛ и Калтана в fixtures не кладём; тесты пакета — на синтетических кандидатах (`tests/builders.py`), прогон реальных файлов — вручную через нормализатор scan-gateway | Файлы заказчика с контура; синтетика воспроизводит обе раскладки строка в строку | Низкая |
| 2026-11-07 | Тип сегмента для разреза — по первым `min_codes` кодам (все одной формы), а не по большинству всех кодов сегмента (исполнение, Task 2) | Строки ОФР без своей шапки прилипают к сегменту пассива ББ с повторной шапкой; по большинству такой сегмент — «ОФР», и разрез по шапке ББ унёс бы пассив в ОФР | Низкая: сегмент, который открывается 1–2 кодами своей формы и дальше идёт чужой, не режется — как до изменения |
| 2026-11-07 | Для разреза — помощник `segments.split_segments` (первая строка, своя шапка, коды сегмента) вместо прямого импорта приватных функций модуля | `split.py` не зависит от приватных имён | Нулевая |
| 2026-11-07 | Редкий столбец отсеивается, только если в строке его числа у всех колонок периода есть числа (финальное ревью, I-1) | Иначе правило молча выбрасывает значение, которое OCR сдвинул из пустой ячейки периода, и документ становится `done` (пассив АК-ЮЛ: итог 1700 = 46922 в столбце «На 2»); сужение совпадает со смыслом решения владельца «постороннее число» | Низкая: обрывок с посторонним числом в строке с пустым периодом остаётся `COLUMN_WITHOUT_DATE` — как до изменения |
| 2026-11-07 | Части `k ≥ 1` получают из предупреждений адаптера `XLSB_NO_FORMATS` (финальное ревью, I-2) | Без него шаг 4 проверяет масштаб xlsb как у файла с форматами: `FRACTIONAL_IN_THOUSANDS` вместо `XLSB_SCALE_SUSPECT` | Нулевая |
## Risks / Trade-offs
- Правило редкого столбца срабатывает и на ББ АК-ЮЛ (прогон 07.11): в сегменте пассива столбец 5 с обрывком «На 2» и
одним числом 46922 (итог 1700 за 31.12.2024, OCR сдвинул его из столбца 6) уходит в `NUMBERS_OUTSIDE_TABLE` (`row:40`).
До изменения этот сегмент сопоставлялся по порядку (`SEGMENT_COLUMNS_MISMATCH`, значения столбца 5 уезжали в колонку
6, настоящие значения столбца 6 терялись); теперь столбец 6 сопоставлен по дате, потеряно одно число, адрес виден
аналитику, жёсткая проверка `1600 = 1700` ловит пустой 1700.
- Пассив ББ АК-ЮЛ (прогон 07.11): столбец «На 2» с одним числом 46922 — сдвинутый OCR итог 1700 за 31.12.2024 (ячейка
столбца периода в этой строке пуста), поэтому после уточнения I-1 правило не срабатывает: поведение прежнее
(`SEGMENT_COLUMNS_MISMATCH`, `needs_check`).
- АК-ЮЛ после разреза: ОФР — отдельный документ, но подписи его колонок 5 («За I п / 20:») и 6 («юлугодие / 25 года»)
ИС тоже разорвала, и ни одна не разбирается как период — столбец 5 не «между периодами», правило редкого столбца не

View File

@ -13,8 +13,9 @@
Часть — обычный `FormCandidate` для шагов 2–8: строки сетки с первой строки сегмента до начала следующей части,
`segment_breaks` — сдвинутые на начало части; `header` — тот же, что у исходного кандидата (шапка файла ИС одна на
таблицу); `source` тот же. Первая часть сохраняет `locator`, `type_hint`, `evidence` и `warnings` исходного кандидата;
следующая часть `k` (с 1) получает `locator = "<locator исходного>;form:<k>"`, `type_hint = null`, пустые `evidence` и
`warnings` — её тип определяется на шаге 6 только по кодам, без `TYPE_CONFLICT` от заголовка таблицы. Кандидат без
следующая часть `k` (с 1) получает `locator = "<locator исходного>;form:<k>"`, `type_hint = null`, пустые `evidence`,
из `warnings` — только предупреждения источника `XLSB_NO_FORMATS` (без них шаг 4 неверно проверяет масштаб xlsb) — её
тип определяется на шаге 6 только по кодам, без `TYPE_CONFLICT` от заголовка таблицы. Кандидат без
смены формы SHALL оставаться одним кандидатом без изменений.
Пакет SHALL экспортировать функцию разреза (`split_by_form(candidate, rules) → tuple[FormCandidate, ...]`); хост
@ -99,12 +100,13 @@ SHALL считаться числами правее таблицы. Подпи
**Редкий столбец с неразобранной подписью** (AURORA-1735, решение владельца 06.11.2026) SHALL НЕ считаться колонкой
сумм, если одновременно: у столбца есть текст подписи, не разобранный ни как период, ни как исключение; левее и правее
него в сегменте есть колонки значений с подписью периода; число стоит не более чем в одной строке с кодом этого
столбца, а в каждой колонке значений сегмента с подписью периода — не менее чем в трёх. Его числа не попадают в значения
столбца, а в каждой колонке значений сегмента с подписью периода — не менее чем в трёх; в строке этого числа у всех
колонок периода тоже есть числа (число лишнее, а не сдвинутое OCR из пустой ячейки периода). Его числа не попадают в значения
строк, `COLUMN_WITHOUT_DATE` не выдаётся; адреса его чисел добавляются в то же предупреждение `NUMBERS_OUTSIDE_TABLE`
(`info`). Если среди адресов предупреждения есть адреса такого столбца, текст — «числа вне колонок формы не
учитываются: …», иначе прежний «числа правее таблицы формы не учитываются: …». Это разорванная OCR подпись периода
(«31» + «а I полугодие 2025 года») с посторонним числом под обрывком; столбец с числами в двух и более строках с кодом
остаётся колонкой с `COLUMN_WITHOUT_DATE`.
остаётся колонкой с `COLUMN_WITHOUT_DATE`; единственное число в строке, где ячейка колонки периода пуста, — тоже.
Подтверждение SHALL опираться только на уверенные источники, чтобы неуверенное не подтверждало само себя: для
неуверенной подписи эффективная дата — дата отчёта с уверенностью 100, иначе самая поздняя абсолютная дата колонок с
@ -157,6 +159,12 @@ SHALL считаться числами правее таблицы. Подпи
двух строках с кодом
- **THEN** столбец остаётся колонкой с `COLUMN_WITHOUT_DATE` уровня `error`
#### Scenario: Значение, сдвинутое в обрывок подписи
- **WHEN** у столбца «31» между колонками периодов одно число «55» в строке 2460, а ячейка колонки периода 2025 этой строки
пуста
- **THEN** столбец остаётся колонкой с `COLUMN_WITHOUT_DATE` уровня `error`, документ `needs_check` — значение не
теряется молча
#### Scenario: Колонка «Изменение»
- **WHEN** правее периодов колонка «Изменение, %»
- **THEN** колонка пропускается, предупреждение `COLUMN_SKIPPED` уровня `info`