From 81081a90c7af623388367853b776e0112508376d Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Wed, 7 Oct 2026 00:16:38 +0400 Subject: [PATCH] =?UTF-8?q?docs(openspec):=20=D1=80=D0=B5=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=E2=84=9617=E2=80=9320=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=B7=20=D0=BE=D0=B1=D1=81=D1=83=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20(=D0=A1=D1=80=D0=B5=D0=B7=203a,=20Task=201=E2=80=935)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2 --- openspec/changes/slice-3a-ocr-normalizer/design.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openspec/changes/slice-3a-ocr-normalizer/design.md b/openspec/changes/slice-3a-ocr-normalizer/design.md index 518e91a..23ffef3 100644 --- a/openspec/changes/slice-3a-ocr-normalizer/design.md +++ b/openspec/changes/slice-3a-ocr-normalizer/design.md @@ -156,3 +156,7 @@ docs: bounded-PR (`03-architecture.md`, OQ-137, §11.1 п. 6 и 9, новые OQ | 15 | 2026-10-06 | Повтор кода строки в таблице OCR: остаётся первая строка, предупреждение, `needs_check` | DBML: уникальный индекс `financial_statement_line (meta_id, line_code)` — без этого маппинг 3b падает; Excel-путь 2b делает так же (§12 п. 5); старое ядро дубли не убирало | вторая строка с тем же кодом теряется в документе (остаётся в `raw/`) | | 16 | 2026-10-06 | `string_value` заполняется только при `amount = null` и непустом не-прочерке, текстом как распознан (`\n`/`\t` → пробел); у разобранных сумм — `null` | DBML `financial_statement_value.string_value`: «как распознано, если не число»; так же в 2b; первичная редакция спеки и старое ядро писали очищенный текст всегда | аналитик не видит сырой текст суммы на экране (он в `raw/`) | | 11 | 2026-10-06 | Имя строки: из словаря редакции по коду; из OCR — только если кода нет в словаре | старое ядро, §11.1 п. 6 | расхождение имени словаря и формы клиента не видно аналитику (видно в `raw/`) | +| 17 | 2026-10-07 | Запись во входящий каталог «без замены» реализуется как `os.link(.part → назначение)` + `unlink(.part)` (локальная ФС), с запасным путём `os.replace` при `EPERM/EXDEV/ENOTSUP`, если назначения нет; на SMB — `smbclient.rename` | POSIX `rename` перезаписывает; жёсткая ссылка атомарно даёт `FileExistsError`; в D-1 сказано «rename без замены» — это его реализация | на ФС без жёстких ссылок окно гонки (проверка существования и `replace`) — повтор задания с тем же `job_id` редок | +| 18 | 2026-10-07 | R-1. Тест плана `test_aep3_like_rows_without_header` требовал `5 in layout.value_idxs`; ожидание заменено на `layout.value_idxs == (2, 4)`, алгоритм `infer_layout` не менялся | столбец 5 содержит только мусор («:», «+ :») и пустые ячейки: по дословному `_infer_layout` суммы (0) < мусор (2) — столбец не значение; ошибка плана, а не переноса | если реальный `aep_3.json` даст иной набор колонок — выяснится в golden (Task 10) | +| 19 | 2026-10-07 | R-2. `line_code_confidence = confidence ячейки кода` только если очищенный текст равен сырому И код есть в выбранной редакции; иначе `min(confidence, 99)`; `line_name_confidence` словарного имени равна `line_code_confidence`, имени из OCR — `confidence` ячейки наименования | требование «Нормализация ответа ИС» спеки; код плана капил уверенность только при мусоре в тексте кода, тест плана ожидал 99 для кода вне справочника | код вне справочника чаще даёт `needs_check` — это то, что нужно аналитику | +| 20 | 2026-10-07 | О-3 (наблюдение, не меняет поведение): прочерк «—»/«–» при `confidence = 100` даёт `is_recognized = false` (дословный `parse_amount` вырезает тире → `verified = false`), дефис «-» — `true` | дословный перенос и формулировка спеки «разбор не отбрасывал символов» | лишний `needs_check` на формах с длинным тире; правило уточняется в §11.1 после проверки на стенде |