plan: итоговый ledger SDD Среза 2b

Refs #26

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
This commit is contained in:
Andrey Epifancev 2026-10-06 22:13:12 +04:00
parent 5b34868784
commit 7de9fd4fd6

View File

@ -116,7 +116,7 @@ Task 12: implementer sonnet DONE_WITH_CONCERNS 10b5bda; make check: 2 failed (go
Task 12: review dispatched (sonnet)
Task 12: review sonnet: spec ✅, Approved (Critical/Important нет). Review Focus 4, 5 покрыты тестами (мутации M1–M5 падают).
Ruling: R-10 — отклонения Task 12 принимаются (флаг dropped: продолжение без колонки кодов → needs_check книги; OTHER-продолжение по правилам ББ; form_name не передаётся) и вносятся в design (#21) — цена ошибки: лишний needs_check на редком листе.
Ruling: R-11 — НПЗ даёт needs_check (1600=1700 расходится на 1.94/9.02/2.48 ₽ в источнике; значения в рублях с копейками при «тыс. руб.»), допуск ±1 по спеке НЕ меняется; ожидание манифеста НПЗ в задаче 14 — needs_check с причиной; выносится владельцу (OQ-138) — цена ошибки: если владелец хочет done — допуск/нормировка в словаре (design #22).
Ruling: R-11 — НПЗ даёт needs_check (1600=1700 расходится на 1.94/9.02/2.48 ₽ в источнике; значения в рублях с копейками при «тыс. руб.»), допуск ±1 по спеке НЕ меняется; ожидание манифеста НПЗ в задаче 14 — needs_check с причиной; выносится владельцу (OQ-137) — цена ошибки: если владелец хочет done — допуск/нормировка в словаре (design #22).
Task 12: golden s12/s14 (синтетика, документы форм вместо заглушки) пересозданы контроллером (make golden-update, diff просмотрен: только s12/s14, статусы done→needs_check и документы форм без колонки кодов), коммит fixtures-wt "test(golden): s12/s14".
Task 12: minor T12.1 (deferred): мёртвые счётчики fractional_values/numeric_values в Draft; предупреждение о дробной части считается по листу, не по документу (спека — «по документу»? уточнить в финале). T12.2 (deferred): ветка lonely_continuation в _is_ok избыточна — комментарий/тест. T12.3 (deferred): can_join игнорирует тип формы при маркере продолжения другого типа. T12.4 (deferred): join O(n·m). T12.5 (deferred): побочный эффект _document дописывает draft.warnings. T12.6 (deferred): test_template_without_sums_is_needs_check вакуумен при пустых lines. T12.7 (deferred): docstring после assert в synthetic documents(). T12.8 (deferred): повторяющийся приём form_name в header.py. T12.9 (deferred): нет теста дубликата внутри продолжения. O-7: D-8 «лист ОСВ между страницами → одиночка» не реализуем интерфейсом (формы получают только листы форм).
Task 12: complete (commits b9e6e31..10b5bda + fixtures golden s12/s14, review clean)
@ -132,3 +132,48 @@ Task 13: fix round 3/5 (3 addressed, 0 open — T13.I1, T13.I2(часть), ми
Task 13: minor T13.5 (deferred → финальная волна): `_upper_header_row` — если в двухстрочном заголовке есть колонка с заполненными обеими ячейками, не склеиваемыми в период («Изменение» над «тыс. руб.»), функция возвращает нижнюю строку и теряет «На 31 декабря» для остальных (предложено: continue вместо return). T13.6 (deferred → финальная волна, до PR): в коммит 4907935 попал случайный артефакт api/uv.lock — убрать.
Task 13: complete (tabular-parser 6f0f05f..4907935; fixtures ff39ad2, f938255, b63c0a5; review clean after round 3)
Пауза после Task 13 (владелец, 06.10.2026)
## Прогон 3 (06.10.2026, контроллер sonnet; продолжение с задачи 14)
Ruling: R-13 (design #23) — решение владельца по R-11, вариант А: допуск ±1 остаётся; баланс НПЗ ожидаемо needs_check (значения в рублях с копейками при шапке «тыс. руб.», 1600 = 1700 расходятся на 1.94/9.02/2.48, OQ-137); INCOME НПЗ — по факту; статус книги по худшему документу. Следствия: манифест T14, спека statement-parsing («Баланс на пяти листах», «Полные формы сходятся»), дельта tabular-recognition-service («Реальные формы через воркер» → needs_check), T15 интеграционный тест ждёт needs_check, T16 §12 п.7 и OQ-137 с примером НПЗ. Цена ошибки: если владелец передумает — допуск/нормировка в словаре.
Модели прогона 3: implementer sonnet, task reviewer sonnet, fix-раунды 4–5 opus, финальное ревью opus.
Task 14: BASE tabular-parser 4907935, fixtures b63c0a5; implementer sonnet dispatched (a2c2bf3000efe1f94)
Task 14: implementer sonnet DONE_WITH_CONCERNS: tabular-parser b6d2089 (openspec R-13/№23), 07d57cb (манифест, property, golden-хелперы, словари); fixtures-wt f017d96 (18+6 снимков). make check 2185 passed; test-fixtures 997 passed за 151 с (порог 288), 1 error test_roundtrip (нет MinIO/NATS — окружение); golden-check 137/137. Файлов форм 18, не 19 (EXPECTED_FILES=18); добавлена синтетика st06.
O-8: ДЕФЕКТ (пропущен ревью T11/T12): checks.py делает relations_failed.append на StatementChecks(), to_wire=exclude_unset → relations_failed/soft_relations_failed никогда не попадают в wire/golden. Фикс — в раунде задачи 14.
Ruling: R-14 (design #24) — INCOME НПЗ и ОФР Унагранде (co 2024-FY, group 2025-Q3 стр.1) по факту needs_check (рубли с копейками при тыс. руб., итоги округлены; 2100 расходится на 17.50/9.43/1416) — та же причина, что R-13/OQ-137; допуск не меняется; сценарий спеки «Знаки 1С» переписывается: abs_terms доказывается юнит-тестом/реальным файлом, где 2100 сходится по факту. Цена ошибки: если владелец хочет done на реальных ОФР — допуск/нормировка единиц (OQ-137).
O-9: лист ОФР НПЗ «…_2» (одна строка 2400, min_codes=3) классифицируется OTHER и пропускается — строка 2400 теряется молча при needs_check документа. Статус: deferred → финальное ревью (решить: предупреждение/правило min_codes для продолжения после открытого документа).
Task 14: fix round 1/5 dispatch (resume implementer): O-8 + спека (Знаки 1С, число листов) + design №24.
Task 14: review sonnet: spec ✅, Needs fixes (Important only): T14.I1 FailedRelation.actual для INCOME считается по варианту без abs_terms (14754604344.76 вместо ≈−71140867.82) — вводит в заблуждение; T14.I2 property-тест вакуумен для complete:false (нет проверки состава relations_failed), per-document status не проверяется, шапка пропускается при None.
Task 14: minor T14.1 (deferred): нет теста уровня документа для checks=None vs checks с пустыми списками. T14.2 (deferred): sheets через locator.count(",") ломается на запятой в имени листа. T14.3 (deferred → финальная волна): design.md шапка и 05-domain-rules.md:762 упоминают ОКВЭД, метка удалена. T14.4 (deferred → финал): шаблон «ББ до» даёт пустой DISCLOSURE done из блока «Примечания» — поведение парсера, закреплено манифестом.
Task 14: fix round 2/5 dispatch (resume implementer): T14.I1, T14.I2
Task 14: minor T14.5 (deferred): document_ok в тесте не покрывает has_code_column/lonely_continuation из _is_ok. T14.6 (deferred): explained_needs_check слабый критерий (checks is None).
Task 14: fix round 1/5 (wire relations_failed O-8, спека, design №24–25; commits 07d57cb..1b17f2e, fixtures 33de51a); fix round 2/5 (2 addressed, 0 open — T14.I1, T14.I2; commits 1b17f2e..6cd2ea8, fixtures ba600fc). make check 2188 passed; test-fixtures 997 passed за 150 с (порог 288), 1 error test_roundtrip (нет compose) — закрыть в T15 через make up; golden-check 137/137.
Task 14: complete (tabular-parser 4907935..6cd2ea8; fixtures b63c0a5..ba600fc; review clean after round 2)
Task 15: BASE tabular-parser 6cd2ea8; implementer sonnet dispatched
Task 15: implementer sonnet BLOCKED (docker daemon off) → контроллер запустил Docker Desktop (open -a Docker; побочный эффект на машине владельца, нужен для make up по заданию) → продолжил: DONE 3a370d4; test-integration 10 passed (НПЗ needs_check, BALANCE relations_failed == {1600 = 1700}); make check 2188 passed. compose парсера остался поднятым (цели down в Makefile нет).
Task 15: review sonnet: spec ✅, Approved. minor T15.1 (deferred → финальная волна): README «Ограничения» п.1 неточен: предупреждение о дробных ≥ порога не влияет на статус; needs_check задают нарушенные соотношения. T15.2 (deferred → финальная волна): тест воркера INCOME проверяет только relations_failed != [] — сравнить множество 2100/2200/2300. T15.3 (deferred): README про golden-update: «лишние снимки» для форм (проверить sync_snapshots). T15.4 (deferred): README: остановка compose — docker compose -f ../docs/dev/docker-compose.yml down.
Task 15: complete (tabular-parser 6cd2ea8..3a370d4, review clean)
Task 16: BASE docs 909e7ff; implementer sonnet dispatched
Task 16: implementer sonnet DONE_WITH_CONCERNS (docs 6d39800, 4272ba8, 00d1715, a5adcac; make check в docs не запускается — нет jsonschema/venv; openspec validate не запускал). Review sonnet: Needs fixes — T16.I1 06-test-data.md:222 «88 файлов (72+16)» противоречит стр.295 (113 = 94+19); добавить expected_statement_parse в дерево. T16.2-4 minor: тексты предупреждений OQ-140 / §12 п.5 / qa-guide неточны («строк без кода с суммами пропущено: N»; «значений с дробной частью при единице тыс. руб.: N из M»); 09-delivery-plan «байт в байт» без ссылки на проверку; статус PR устареет после merge.
O-10: design.md D-11 (tabular-parser change) всё ещё обещает НПЗ done; design шапка/05-domain-rules:762 упоминают ОКВЭД — править в финальной волне (T14.3).
Task 16: fix round 1/5 dispatch (resume): T16.I1 + T16.2/T16.3
Task 16: fix round 1/5 (3 addressed, 0 open — T16.I1, T16.2, T16.3; docs 4729e40). Re-review: All findings addressed.
Task 16: complete (docs 909e7ff..4729e40, review clean after round 1). Minor T16.4 (deferred): статус PR в 09-delivery-plan устареет после merge.
Task 17 (часть 1: merge origin/main, check-full, golden-check, openspec, tasks.md) — исполняет контроллер-диспатч; PR-описания — после финального ревью и волны фиксов.
O-11: origin/main docs ушёл вперёд (PR #35…#43): в main уже занят OQ-137 (раскладка горячих папок ИС Сканирование); merge origin/main в docs даёт конфликты в 07-open-questions.md и dev/qa-guide.md.
Ruling: R-15 (design #26) — наши новые OQ-137…OQ-142 перенумерованы в OQ-138…OQ-143 (номер OQ-137 в main занят другим вопросом, перенумерация нашего дешевле, чем чужого); правки во всех ссылках docs (context, plan, ledger-копия) и tabular-parser (README, CLAUDE.md, спека, design, манифест, тест воркера). Цена ошибки: ссылки на OQ-13x в уже открытых PR-описаниях/комментариях — в описаниях пишем новые номера.
Task 17 ч.1: docs merge origin/main e93b28e + перенумерация 9235e6a (R-15), tabular-parser be47e82; make check-full EXIT 0; openspec validate valid. Финальное ревью (opus) dispatched.
## Финальное ревью (opus): Ready to merge — With fixes
I-1 (=O-9): лист с единственной кодовой строкой 2400 теряется, предупреждение «skipped: нет признаков ОСВ или формы» неверно; противоречит §12 п.9. I-2 (=T8.5): bounds_span «одиночный месяц» даёт неверные period_start/is_from_year_start («на 31 декабря 2024 г.» → 12-01). I-3 (новая): пустой line_name при confidence=100 у итогов/«в том числе» (ОФР 2200/2300/2411/2412/2400, ББ 15401/15402): имя в соседней колонке. M-1 (=T13.6) uv.lock. M-2 tasks.md обоих change не [x]. M-3 (=O-10) D-11 НПЗ done. M-4 устаревший §1.1 05-domain-rules.md:244 и README:150 про «skipped: statement (slice 2b)». M-5 слово «тыс» (lines.py:20) и _OKUD_CODE (detect.py:20, T6.2) в коде — нарушение Global Constraint. M-6 (=T6.1). M-7 (=T10.7). M-8 строка нумерации на разрыве страницы и нули считаются «строкой без кода с суммами». M-9 подстроки с 10-го номера (11510, 15110…) не в _subline_rules. M-10 (=T12.3) can_join без типа формы. M-11 (=T12.1). M-12 примеры контракта (T2.2/T2.3 + result-statement-excel без 1700 при relations_failed=[]) — по R-4 follow-up. T13.5: простой continue опасен (сломает защиту «Единица измерения» над датами); правильно — возвращать верхнюю строку, если хотя бы одна колонка склеилась в период.
Ruling: R-16 (design #27) — единая волна фиксов: I-1 (присоединение листа как продолжения с ослабленным min_codes=1 после листа формы, запасной вариант dropped+точное предупреждение) + M-10, I-2, I-3, M-1, M-2, M-3, M-4, M-5(+T6.2), M-6, M-7, M-8, M-11, T13.5 (по рекомендации ревьюера), T15.1, T15.2. Follow-up (deferred в issue): M-9, M-12, остальные minor из ledger. Цена ошибки: I-1 расширяет парсер после ревью задач (риск регрессии) — ловит один scoped re-review и golden-check.
Final wave (R-16) DONE: tabular-parser 336f4d6 (M-1), 1abe212 (I-1/O-9, M-10, I-2/T8.5, I-3, M-5/T6.2, M-8, M-11/T12.1, T13.5, M-6/T6.1, M-7/T10.7, T15.1, T15.2), 15fb561 (design №25/D-11/R-16 №27, tasks.md, спека); docs 5b34868 (OQ-143, M-4, tasks.md); fixtures 9586207 (golden + st07). make check 2205; golden-check 138/138; test-fixtures 1003 за 149 с; test-integration 10; openspec valid; golden ОСВ без изменений. tasks.md: оставлены [ ] — T п.5.1 (README/check-full/PR — до PR), docs п.3 (синхронизация при архивации).
O-12: в трейлере Claude-Session коммитов волны — URL сессии из системной подсказки вместо UUID (разночтение системных инструкций); историю не переписываем; цена: единообразие трейлера.
Re-review волны (opus): All findings addressed (I-1, M-10, I-2, I-3, M-5, M-8, M-11, T13.5, M-1, M-6, M-7, T15.1, T15.2, M-3, M-4, M-2). Новые находки в fix-diff (Minor, адьюдикация, второй волны нет):
N-1 (deferred, follow-up; значимая): ослабленный порог (min_codes_continuation=1) допускает ложные присоединения: лист «Справка»/«Сведения» с единственным числом в диапазоне кодов (или 5-значным ОКОПФ) после формы → при совпадении числа колонок строка молча присоединяется к последнему документу и может остаться done; при несовпадении книга needs_check вместо done+skipped. Реальные фикстуры не затронуты. Меры (follow-up): охрана «сразу после листа формы», числа во всех колонках периодов, негативные BookParser-тесты.
N-2 (deferred): book.py:109 проверяет «была какая-то форма раньше», а не «сразу после листа формы» (спека/README говорят иначе).
N-3 (deferred): нет негативных BookParser-тестов шлюза (форма+посторонний лист; одиночный лист с одной кодовой строкой; ОСВ+лист с одним кодом).
N-4 (deferred): note_cols заполняются только при шапке таблицы; на продолжении без шапки значения «Пояснения» («5.1») могут стать line_name.
N-5 (deferred): design.md D-10 говорит «periods.yaml не правится», I-2 правит periods.yaml (not_single_month): противоречие текста и конфликт при rebase на #11 — править текст при follow-up/слиянии.
O-13: интеграционный прогон волны не был показан в отчёте → контроллер прогоняет make check-full сам перед PR.
Финал: fix волна закрыта; финальные проверки контроллером; PR-описания.
Финальные проверки контроллера: make check-full EXIT 0 (интеграция 10 passed); golden-check 138/138; openspec validate --strict valid в обоих репо.
Следующий шаг: push веток (без force), обновление PR #16 / #27, PR fixtures, удаление workspace.