Follow-ups from #6 #9

Closed
opened 2026-10-07 04:06:47 +03:00 by aep · 1 comment
Owner

Отложенные находки Среза 3a (scan-gateway PR #8, change slice-3a-ocr-normalizer, решения №17–35 в design.md). Маркер — одна строка — откуда.

Важное (решение владельца)

  • I-2 — повтор кода 2410 в ОФР aep_6.json: по правилу №15 «первая строка» теряется сумма (649) второй строки (остаётся только в raw/); вопрос «первая строка или первая с суммой» — OQ-152 — финальное ревью opus.
  • T14.6 / OQ-151 — эмулятор: PDF совпал по хешу, а JSON-набора нет (aep_4.PDF) → «нет пары» без перехода на SCAN_EMULATOR_DEFAULT; «пар: N» считает все не-JSON файлы; одинаковые байты у двух PDF — ревью Task 14.
  • T15.7 — источник «Приложения 3–4 ФСБУ 4/2023» для редакции fsbu4 в README не проверен — ревью Task 15.

Справочники и правила

  • T1.4 — test_rules: isinstance(Edition, type) бессмысленно; test_settings_defaults зависит от окружения/.env — ревью Task 1.
  • T1.5 — rules.py: assert isinstance(...) для сужения типов — ревью Task 1.
  • T1.6 — нет валидации пересечения интервалов редакций, valid_from > valid_until, нормализации ключей labels — ревью Task 1.
  • T1.7 — Edition frozen, но lines — изменяемый dict — ревью Task 1.
  • T1.8 — тест данных 66n не сверяет весь набор ключей — повторное ревью Task 1.
  • RR-1 — YAML merge keys (<<:) ломают загрузку правил (следствие №33, запрет повторяющихся ключей) — повторное финальное ревью.

Конвейер нормализации

  • T2.2 — test_text: не покрыта ветка «| при буквах в первой строке» — ревью Task 2.
  • T2.3 — нет тестов на •/· в строке-разделителе — ревью Task 2.
  • T3.1 — dates.py: лишние # noqa: PLR2004 — ревью Task 3.
  • T3.3 — при переносе потерян комментарий # "30 09 25", # ГГГГ ДД ММ переехал — ревью Task 3.
  • T3.4 — отчёт исполнителя неполно перечисляет добавленные подавления (обоснованы) — ревью Task 3.
  • T3.5 — нет теста на 2-й/4-й квартал — ревью Task 3.
  • RR-4 — тесты ограничения длины текста дат (№31) не различают caller-side лимит — повторное финальное ревью.
  • T4.1 — test_amounts не покрывает -, +, (-5), (+5), (), «—» — ревью Task 4.
  • T4.3 — (0) → Decimal("-0"), как в источнике — ревью Task 4.
  • T5.1 — cells_by_index: confidence-строка → 0.0, bool проходит isinstance — ревью Task 5.
  • T5.2 — column_index типа bool принимается, строковый индекс пропускается; не покрыто тестом — ревью Task 5.
  • T5.5 — нет тестов: ячейка без column_index, label_idx=None, полностью пустой столбец значений — ревью Task 5.
  • T6.1 — test_second_header_overrides_layout: обе шапки с одинаковыми code_idx/label_idx — чтение по новой раскладке не доказано — ревью Task 6.
  • T6.2 — test_aep6_balance_with_header не проверяет, что повторная шапка (строка 72) не попала в строки — ревью Task 6.
  • T6.3 — нет теста запасного _ordinal (нецелый row_index) — ревью Task 6.
  • T7.2 — docstring header.py: «распознано = confidence 100 и сырой текст без мусора» верно только для ИНН — ревью Task 7.
  • T7.3 — bool/nan принимаются как confidence в шапке — ревью Task 7.
  • T7.4 — нет тестов: организация с \n, inn_confidence = None для aep_6, поле-не-объект — ревью Task 7.
  • T8.10 — R-5 подавляет «код из редакции» и при edition is None — повторное ревью Task 8.
  • T8.11 — предупреждение о смене числа колонок считается до дедупликации кодов — ревью Task 8.
  • M-3 — предупреждение «повторная шапка…» может сработать без повторной шапки (выведенная раскладка) — финальное ревью.
  • T9.2 — needs_check без предупреждения при organization_name_confidence < 100; table_structure не список → RECOGNITION_FAILED без warning — ревью Task 9.
  • T9.5 — пробелы тестов: исключение вне таблицы, ИНН с confidence < 100, metrics.rows по нескольким документам; имя test_needs_check_with_table_warning вводит в заблуждение — ревью Task 9.

Golden

  • T10.3 — aep_3: header.units = «тыс. руб. год по ОКЕИ 13184» (clean_value по спеке) и ~32 КБ мусора в organization_name — ревью Task 10.
  • T10.4 — код 420 (вероятно 1420) попадает в документ без предупреждения (код нигде не найден → confidence 99) — ревью Task 10.
  • T10.5 — aep_6: все line_code_confidence = 99, имена из OCR, пока fsbu4 пуста — ожидаемо — ревью Task 10.
  • T10.6 — golden_update.golden_cases дублирует логику эмулятора; нет проверки «осиротевших» эталонов — ревью Task 10.
  • T10.7 — test_golden красный, если ../fixtures/ocr есть, а expected_normalize/ нет; рассмотреть skip — ревью Task 10.
  • M-5 — naming: aep_8_form4 — основной файл в golden против <uuid>_form4.json у эмулятора — финальное ревью.

Горячие папки, воркер, эмулятор

  • T11.5 — нет теста запасного os.replace; ветка os.replace не вызывает _drop_part; нет теста падения unlink Input/<name> — ревью Task 11.
  • T12.4 — SMB cleanup: ENOENT при remove/rmdir после scandir пробрасывается; вложенный каталог в Output/<job_id>/ роняет rmdir (в local — rmtree) — ревью Task 12.
  • T12.6 — дублирование в тестах TestCleanup; учётные данные в cleanup не проверены — ревью Task 12.
  • T12.7 — mypy-ошибка в tests/unit/test_smb_hotfolder.py:529 (mypy в make lint проверяет только src) — ревью Task 12.
  • RR-3 — symlink-.part в Tmp обходит проверку st_nlink (нужен посторонний актор в Tmp); O_NOFOLLOW/S_ISREG — повторное финальное ревью.
  • RR-5 — режим .part 0o644 вместо 0o666 & ~umask — повторное финальное ревью.
  • T13.2 — нет тестов очистки на неуспешных исходах (INVALID_DOCUMENT, исключение нормализатора) и порядка «после raw/» — ревью Task 13.
  • T13.5 — test_existing_input_waits_for_answer не проверяет puts и остаток .part — ревью Task 13.
  • T13.6 — test_create_app_uses_ocr_normalizer зависит от cwd = api/ — ревью Task 13.
  • M-4 — worker.py: строка-ограничитель «все ошибки файлов — в raw/» устарела (теперь там и предупреждения нормализации) — финальное ревью.
  • T15.6 — test_roundtrip: комментарий над OK_DOC_PDF; FileNotFoundError вместо skip без aep_5.json; теоретическая гонка сценария очистки; golden-сверка молча пропускается без expected_normalize — ревью Task 15.

Документы (docs PR #47)

  • docs-M1 — формулировка «кубическое/экспоненциальное» про разбор дат — ревью docs.
  • docs-M2…M4 — мелкие формулировки docs-ревью (признаны не влияющими на смысл, детали в ledger не сохранены) — ревью docs.

Открытые вопросы владельцу (в docs/context/07-open-questions.md): OQ-144 права на удаление на SMB, OQ-145 редакция формы в контракте, OQ-148 длинное тире при confidence 100, OQ-149 строки с пустым/мусорным кодом, OQ-151 эмулятор без JSON-набора, OQ-152 повтор кода.

Отложенные находки Среза 3a (scan-gateway PR #8, change `slice-3a-ocr-normalizer`, решения №17–35 в `design.md`). Маркер — одна строка — откуда. ## Важное (решение владельца) - **I-2** — повтор кода 2410 в ОФР `aep_6.json`: по правилу №15 «первая строка» теряется сумма `(649)` второй строки (остаётся только в `raw/`); вопрос «первая строка или первая с суммой» — OQ-152 — финальное ревью opus. - **T14.6 / OQ-151** — эмулятор: PDF совпал по хешу, а JSON-набора нет (`aep_4.PDF`) → «нет пары» без перехода на `SCAN_EMULATOR_DEFAULT`; «пар: N» считает все не-JSON файлы; одинаковые байты у двух PDF — ревью Task 14. - **T15.7** — источник «Приложения 3–4 ФСБУ 4/2023» для редакции `fsbu4` в README не проверен — ревью Task 15. ## Справочники и правила - **T1.4** — `test_rules`: `isinstance(Edition, type)` бессмысленно; `test_settings_defaults` зависит от окружения/.env — ревью Task 1. - **T1.5** — `rules.py`: `assert isinstance(...)` для сужения типов — ревью Task 1. - **T1.6** — нет валидации пересечения интервалов редакций, `valid_from > valid_until`, нормализации ключей `labels` — ревью Task 1. - **T1.7** — `Edition` frozen, но `lines` — изменяемый dict — ревью Task 1. - **T1.8** — тест данных 66n не сверяет весь набор ключей — повторное ревью Task 1. - **RR-1** — YAML merge keys (`<<:`) ломают загрузку правил (следствие №33, запрет повторяющихся ключей) — повторное финальное ревью. ## Конвейер нормализации - **T2.2** — `test_text`: не покрыта ветка «`|` при буквах в первой строке» — ревью Task 2. - **T2.3** — нет тестов на `•`/`·` в строке-разделителе — ревью Task 2. - **T3.1** — `dates.py`: лишние `# noqa: PLR2004` — ревью Task 3. - **T3.3** — при переносе потерян комментарий `# "30 09 25"`, `# ГГГГ ДД ММ` переехал — ревью Task 3. - **T3.4** — отчёт исполнителя неполно перечисляет добавленные подавления (обоснованы) — ревью Task 3. - **T3.5** — нет теста на 2-й/4-й квартал — ревью Task 3. - **RR-4** — тесты ограничения длины текста дат (№31) не различают caller-side лимит — повторное финальное ревью. - **T4.1** — `test_amounts` не покрывает `-`, `+`, `(-5)`, `(+5)`, `()`, «—» — ревью Task 4. - **T4.3** — `(0)` → `Decimal("-0")`, как в источнике — ревью Task 4. - **T5.1** — `cells_by_index`: confidence-строка → 0.0, `bool` проходит `isinstance` — ревью Task 5. - **T5.2** — `column_index` типа `bool` принимается, строковый индекс пропускается; не покрыто тестом — ревью Task 5. - **T5.5** — нет тестов: ячейка без `column_index`, `label_idx=None`, полностью пустой столбец значений — ревью Task 5. - **T6.1** — `test_second_header_overrides_layout`: обе шапки с одинаковыми `code_idx/label_idx` — чтение по новой раскладке не доказано — ревью Task 6. - **T6.2** — `test_aep6_balance_with_header` не проверяет, что повторная шапка (строка 72) не попала в строки — ревью Task 6. - **T6.3** — нет теста запасного `_ordinal` (нецелый `row_index`) — ревью Task 6. - **T7.2** — docstring `header.py`: «распознано = confidence 100 и сырой текст без мусора» верно только для ИНН — ревью Task 7. - **T7.3** — `bool`/`nan` принимаются как confidence в шапке — ревью Task 7. - **T7.4** — нет тестов: организация с `\n`, `inn_confidence = None` для aep_6, поле-не-объект — ревью Task 7. - **T8.10** — R-5 подавляет «код из редакции» и при `edition is None` — повторное ревью Task 8. - **T8.11** — предупреждение о смене числа колонок считается до дедупликации кодов — ревью Task 8. - **M-3** — предупреждение «повторная шапка…» может сработать без повторной шапки (выведенная раскладка) — финальное ревью. - **T9.2** — `needs_check` без предупреждения при `organization_name_confidence < 100`; `table_structure` не список → `RECOGNITION_FAILED` без warning — ревью Task 9. - **T9.5** — пробелы тестов: исключение вне таблицы, ИНН с confidence < 100, `metrics.rows` по нескольким документам; имя `test_needs_check_with_table_warning` вводит в заблуждение — ревью Task 9. ## Golden - **T10.3** — aep_3: `header.units` = «тыс. руб. год по ОКЕИ 13184» (`clean_value` по спеке) и ~32 КБ мусора в `organization_name` — ревью Task 10. - **T10.4** — код `420` (вероятно 1420) попадает в документ без предупреждения (код нигде не найден → confidence 99) — ревью Task 10. - **T10.5** — aep_6: все `line_code_confidence = 99`, имена из OCR, пока `fsbu4` пуста — ожидаемо — ревью Task 10. - **T10.6** — `golden_update.golden_cases` дублирует логику эмулятора; нет проверки «осиротевших» эталонов — ревью Task 10. - **T10.7** — `test_golden` красный, если `../fixtures/ocr` есть, а `expected_normalize/` нет; рассмотреть skip — ревью Task 10. - **M-5** — naming: `aep_8_form4` — основной файл в golden против `<uuid>_form4.json` у эмулятора — финальное ревью. ## Горячие папки, воркер, эмулятор - **T11.5** — нет теста запасного `os.replace`; ветка `os.replace` не вызывает `_drop_part`; нет теста падения unlink `Input/<name>` — ревью Task 11. - **T12.4** — SMB `cleanup`: ENOENT при `remove/rmdir` после `scandir` пробрасывается; вложенный каталог в `Output/<job_id>/` роняет `rmdir` (в local — `rmtree`) — ревью Task 12. - **T12.6** — дублирование в тестах `TestCleanup`; учётные данные в `cleanup` не проверены — ревью Task 12. - **T12.7** — mypy-ошибка в `tests/unit/test_smb_hotfolder.py:529` (mypy в `make lint` проверяет только `src`) — ревью Task 12. - **RR-3** — symlink-`.part` в `Tmp` обходит проверку `st_nlink` (нужен посторонний актор в `Tmp`); `O_NOFOLLOW`/`S_ISREG` — повторное финальное ревью. - **RR-5** — режим `.part` 0o644 вместо `0o666 & ~umask` — повторное финальное ревью. - **T13.2** — нет тестов очистки на неуспешных исходах (`INVALID_DOCUMENT`, исключение нормализатора) и порядка «после `raw/`» — ревью Task 13. - **T13.5** — `test_existing_input_waits_for_answer` не проверяет `puts` и остаток `.part` — ревью Task 13. - **T13.6** — `test_create_app_uses_ocr_normalizer` зависит от `cwd = api/` — ревью Task 13. - **M-4** — `worker.py`: строка-ограничитель «все ошибки файлов — в raw/» устарела (теперь там и предупреждения нормализации) — финальное ревью. - **T15.6** — `test_roundtrip`: комментарий над `OK_DOC_PDF`; `FileNotFoundError` вместо skip без `aep_5.json`; теоретическая гонка сценария очистки; golden-сверка молча пропускается без `expected_normalize` — ревью Task 15. ## Документы (docs PR #47) - **docs-M1** — формулировка «кубическое/экспоненциальное» про разбор дат — ревью docs. - **docs-M2…M4** — мелкие формулировки docs-ревью (признаны не влияющими на смысл, детали в ledger не сохранены) — ревью docs. Открытые вопросы владельцу (в `docs/context/07-open-questions.md`): OQ-144 права на удаление на SMB, OQ-145 редакция формы в контракте, OQ-148 длинное тире при confidence 100, OQ-149 строки с пустым/мусорным кодом, OQ-151 эмулятор без JSON-набора, OQ-152 повтор кода.
Author
Owner

Нормализатор Среза 3a вырезан в #46, большая часть списка потеряла смысл; повтор кода 2410 (OQ-152) теперь сохраняет обе строки. Живое по SMB и эмулятору перенёс в #29. Закрываю.

Нормализатор Среза 3a вырезан в #46, большая часть списка потеряла смысл; повтор кода 2410 (OQ-152) теперь сохраняет обе строки. Живое по SMB и эмулятору перенёс в #29. Закрываю.
aep closed this issue 2026-10-25 19:17:23 +03:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/arm-scan-gateway#9
No description provided.