arm-ka-docs/docs/superpowers/plans/2026-10-06-slice-2b-statement-parser-ledger.md
Andrey Epifancev 909e7ff084 plan: ledger SDD Среза 2b после задачи 13 (пауза 06.10.2026)
Копия .superpowers/sdd/…/progress.md для продолжения на другой машине: задачи 1–13 complete, рулинги R-1…R-12,
находки deferred, пауза перед задачей 14.

Refs #26

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 19:40:29 +04:00

135 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SDD ledger — plan: docs/superpowers/plans/2026-10-06-slice-2b-statement-parser.md
Прогон 1: задачи 1–3. Задачи 4–17 — следующий прогон по этому же ledger.
Plan file (абс.): /Users/andrey.epifancev/projects/awp-ca/.wt/slice-2b/docs/docs/superpowers/plans/2026-10-06-slice-2b-statement-parser.md
Spec: tabular-parser/openspec/changes/slice-2b-statement-parser/ и docs/openspec/changes/slice-2b-statement-parser/ (прочитаны реализаторами по брифу, контроллер — выборочно).
Setup: tabular-parser venv создан, codegraph init выполнен (worktree), .superpowers/ в .gitignore docs — есть.
## Pre-flight scan (по всему плану, 17 задач)
| Пара задач / задача | Разделяют | Производит / потребляет | Найдено |
|---|---|---|---|
| T1 -> T2 | схема v1.2, примеры | T1 пишет DOCS/contracts; T2 cp в API/contracts, байт в байт | согласовано; T2 зависит от коммита T1 (порядок есть) |
| T1 -> T3 | схема, примеры | T3 копирует DOCS/contracts в arm-core/scan-gateway | согласовано |
| T2 <-> T3 | правки result.py (модели) | T3 повторяет модели T2 в двух репо; CONTRACT_VERSION не менять | согласовано; в T3 пути тестов существуют (arm-core/api/tests/test_contract.py, scan-gateway/api/tests/unit/test_contract.py) |
| T4 -> T5,T6,T9,T11 | rules.py, statement_*.yaml | T4 производит Rules.statement_*; потребляют T5/T6/T9/T11 | согласовано |
| T4 <-> T6 | rules.py, osv_headers.yaml | T6 удаляет statement_markers после T4 | порядок последовательный, конфликта нет |
| T5 -> T6,T9,T10 | TableLayout, line_code, cell_label | интерфейсы совпадают с Consumes | согласовано |
| T6 -> T9,T12 | FormBlock, classify_statement_sheet | согласовано | |
| T7 <-> T8 <-> T12 | osv.py, book.py, test_book_parser.py | T7 создаёт book.py и SkippingStatementParser, T8 правит osv.py::_header, T12 удаляет заглушку | порядок последовательный; согласовано |
| T10 -> T11 -> T12 | StatementLine, checks | согласовано | |
| T13 -> T14 -> T15 | fixtures_helpers, синтетика, golden | T13/T14 пишут в fixtures worktree feat/14-statements-golden | зависимость от fixtures PR; вне прогона 1 |
| T16, T17 | docs, PR | вне прогона 1 | |
| Каждая задача (само-согласованность) | | T1: тест-скрипт в scratchpad и шаги согласованы. T2: файла result_contract.py нет (указано «нет»), grep "1.1" в tests пока пуст — шаг допустим. T3: в плане сказано "Не менять CONTRACT_VERSION" — консистентно. Задачи 4–17 проверены по Files/Interfaces (grep), содержимое шагов будет сверено в прогоне 2. | |
Конфликтов плана с Global Constraints и review rubric в Files/Interfaces не обнаружено.
Ruling: R-1 — план требует в Task 1 Step 1 временный скрипт в scratchpad; использую путь scratchpad контроллера — тот же что в плане — цена ошибки нулевая.
Замечания по окружению: T1 в плане использует `API/.venv/bin/python` tabular-parser (jsonschema есть); T3 — командой `make venv` в arm-core/scan-gateway.
BASE T1: docs ca8615e
Task 1: implementer haiku DONE, commit 82ad2ab (docs). Review dispatched (sonnet).
Task 1: minor T1.1 (deferred): $comment схемы упоминает «1.1» — plan-mandated не трогать; поправить в follow-up.
Task 1: minor T1.2 (deferred): format:date не проверяется без format_checker в check-скрипте; не влияет на контракт.
Task 1: minor T1.3 (rejected: косметика примера, число «3» произвольно).
Task 1: complete (commits ca8615e..82ad2ab, review clean)
Task 2: BASE tabular-parser 37b25e0; implementer haiku dispatched
Task 2: implementer DONE, commit 3a08b99; tests 2028 passed.
O-1: implementer запустил make golden-update, что переписало 113 golden-файлов (только schema_version 1.1->1.2) в ОСНОВНОМ checkout fixtures на main (через симлинк; не закоммичено). Откат (git restore) заблокирован классификатором — оставлено человеку. Статус: deferred (человек: git -C fixtures restore -- golden, либо оставить для Task 14, где golden пересоздаются в worktree feat/14-statements-golden). Правка вне плана (план: golden только в worktree-ветке + отдельный коммит).
Task 2: minor T2.1 (deferred): $comment схемы «1.1» (= T1.1, plan-mandated).
Task 2: minor T2.2 (deferred): пример result-statement-excel.json status needs_check при одном мягком нарушении — вводит в заблуждение; поправить в docs (plan-mandated пример).
Task 2: minor T2.3 (deferred): result-statement-minimal.json (OCR) получил checks с пустыми списками, что противоречит семантике «нет объекта = не проверялось»; plan-mandated.
Task 2: minor T2.4 (rejected: необязательные негативные тесты, вне брифа).
Task 2: complete (commits 37b25e0..3a08b99, review clean)
Task 3: implementer DONE: arm-core 46d17e6, scan-gateway e2f1bb5; make check: arm-core 1108 passed, scan-gateway 749 passed.
Ruling: R-2 — в scan-gateway копия схемы отставала на v1.1 (не было OsvRow.extra и примера result-osv-needs-check.json); принят догон v1.1 вместе с v1.2 (копия обязана совпадать с docs побайтно) — если неверно: лишний необязательный OsvRow.extra в scan-gateway, откатывается отдельным коммитом (design #13, см. design.md).
Task 3: minor T3.1 (fixed в описании PR: упомянут догон v1.1).
Task 3: minor T3.2 (fixed в описании PR: CONTRACT_VERSION остаётся 1.0).
Task 3: complete (arm-core origin/main..46d17e6, scan-gateway origin/main..e2f1bb5, review clean)
R-2 (design #12). PR: arm-core#27, arm-scan-gateway#5 созданы. design.md решения №12–13 закоммичены в tabular-parser.
Пауза после Task 3: ждём мержа PR копий схемы
## Прогон 2
Ruling: R-3 — golden schema_version 1.1->1.2 пересозданы в worktree fixtures (.wt/slice-2b/fixtures-wt, ветка feat/14-statements-golden, коммит bf8c88f, diff только schema_version, 113 файлов); симлинк fixtures переключён на fixtures-wt (шаг 1 T13 выполнен контроллером); основной checkout fixtures не тронут (O-1 остаётся человеку) — чтобы make check был зелёным на каждой задаче; цена ошибки: коммит в fixtures-ветке раньше плана, откат — reset ветки (design #14).
Task 4: BASE tabular-parser ed516d8; implementer haiku dispatched
Ruling: R-4 (от координатора, design #15) — docs/contracts/** после задачи 1 заморожены, в задаче 16 НЕ править; T1.1/T2.1/T2.2/T2.3 остаются deferred и идут в follow-up issue при закрытии — копии в arm-core#27 и scan-gateway#5 на ревью и должны остаться байт в байт; цена ошибки: три косметических замечания живут до следующего MINOR.
Task 4: implementer haiku DONE d21884e; 2046 passed. Review (sonnet): spec ❌ 1 Important: okud DISCLOSURE pattern statement_headers.yaml:103 `\b0710(?!001|002)` вместо брифа `\b07100(0[3-9]|[1-9]\d)\b` (T4.I1).
Task 4: minor T4.1 (deferred): RelationRule.target/.terms перепарсиваются на каждый доступ.
Task 4: minor T4.2 (deferred): шесть одинаковых any(...) методов — хелпер _any.
Task 4: minor T4.3 (deferred): нет проверки lo<=hi в _LineCodeRules._check.
Task 4: minor T4.4 (deferred): FormType не в __all__.
Task 4: minor T4.5 (deferred): нет негативных тестов (_check_required_keys, abs_terms, target in codes, группы периода, okopf vs okopf_okfs, границы okud).
Task 4: minor T4.6 (deferred): комментарий statement_periods.yaml:5 про обязательные группы неточен, m1 не валидируется.
Task 4: fix round 1/5 (1 addressed, 0 open — T4.I1 okud pattern; commits d21884e..6a3661c)
Task 4: complete (commits ed516d8..6a3661c, review clean)
Task 5: BASE 6a3661c; implementer haiku dispatched
Task 5: implementer haiku DONE c3df9ff; make check (контроллер) 2058 passed. Review sonnet: spec ✅, approved.
Task 5: minor T5.1 (deferred): мёртвые noqa columns.py:136,211. T5.2 (deferred): шумные константы в test_columns.py. T5.3 (deferred): ветка code_col_empty and no_numbers не покрыта тестом (plan-mandated). T5.4 (deferred): лишние вычисления до проверки following<first_code_row. T5.5 (deferred): «Пояснения» ищется только в header_row, не в header_last_row.
Task 5: O-2: отчёт реализатора не содержал вывода make check; контроллер прогнал сам.
Task 5: complete (commits 6a3661c..c3df9ff, review clean)
Task 6: BASE c3df9ff; implementer haiku dispatched
Task 6: implementer haiku DONE b8bf2f2; 2061 passed. Review sonnet: spec ✅ с Important T6.I1: osv.py:231-240 не обрабатывает SheetKind.STATEMENT_CONTINUATION (проваливается в parse_sheet).
Ruling: R-5 — T6.I1 не чинится в задаче 6: osv.py::parse заменяется BookParser в Task 7 (STATEMENT_KINDS = STATEMENT|STATEMENT_CONTINUATION, brief T7), реальные фикстуры ОСВ не содержат листов-продолжений (golden/make check зелёные), промежуточная регрессия невидима; задача 7 обязана покрыть продолжение в книге с ОСВ (тест) — цена ошибки: если T7 не покроет, ловит финальное ревью (design #16).
Task 6: minor T6.1 (deferred; в финальной волне/T16): устаревшие упоминания statement_markers (tests/fixtures/test_rules_coverage.py:4, tests/synthetic/generate.py:560, rules/README.md «Покрытие словарей»). T6.2 (deferred): _OKUD_CODE литерал в detect.py, английский комментарий, два type: ignore. T6.3 (deferred): производительность classify_sheet/find_forms. T6.4 (deferred): пробелы в тестах (маркер продолжения не создаёт блок; заголовок после продолжения; fixtures-тест классификации форм — придёт в T14). T6.5 (deferred): риск ложного «продолжения» на листах «прочее» с колонкой кодов.
Task 6: complete (commits c3df9ff..b8bf2f2, 1 Important перенесён рулингом R-5)
Task 7: BASE b8bf2f2; implementer sonnet dispatched
Task 7: implementer sonnet DONE_WITH_CONCERNS 43ee753 (+fixtures d811519 golden s06/s12/s14 — порядок предупреждений: формы разбираются пачкой после ОСВ-листов, следует из структуры брифа; Step 4 брифа неточно обещал diff только у s06); make check 2066 passed. Review sonnet: approved, R-5 покрыт тестом test_statement_continuation_is_not_parsed_as_osv (T6.I1 закрыт).
Task 7: minor T7.1 (deferred): при ошибке ОСВ-листа предупреждения пропуска форм не попадают в ответ с ошибкой. T7.2 (deferred): семантика metrics.rows для форм (len(lines)) не зафиксирована. T7.3 (observation O-3): бриф Step 4 неточен про golden s12/s14.
Task 7: complete (commits b8bf2f2..43ee753 + fixtures d811519, review clean)
Task 8: BASE 43ee753; implementer sonnet dispatched
Task 8: implementer sonnet DONE 8990ab2 (+fixtures 8b9c22a: 113 файлов, только 3 новых поля); make check 2074 passed. Review sonnet: Needs fixes — Important T8.I1: header.py:371-376/_parse_period + rules.py:284 month_range: «Январь - Май 2025 г.» (диапазон от января без года начала, кроме концов-кварталов) даёт period_end 2025-12-31 и is_from_year_start=True без предупреждения (неверные новые поля).
Task 8: minor T8.1 (deferred): тест через книгу проверяет только True-вариант _from_year_start. T8.2 (deferred): test_period_bounds вычисляет from_year_start из period_start, дублирует. T8.3 (deferred): недостижимая ветка is_cumulative is None в _bounds. T8.4 (deferred): мало тестов конца месяца.
Task 8: fix round 1/5 dispatched (resume implementer): T8.I1
Task 8: fix round 1/5 (1 addressed, 0 open — T8.I1; commits 8990ab2..f279157)
Task 8: minor T8.5 (deferred → финальная волна фиксов, приоритет высокий): ветка «одиночный месяц» в PeriodRules.bounds_span (rules.py) слишком широкая: «на 31 декабря 2024 г.» → границы 2024-12-01..12-31 вместо 2024-01-01..12-31 при Q4/cumulative; «1 квартал 2025 г. (по состоянию на 31 марта)» → 03-01..03-31. В корпусе golden таких случаев нет. Фикс: применять только когда текст — один месяц и год без квартальных/годовых/«N месяцев» слов.
Task 8: out-of-scope O-4: для «Январь - Май 2025 г.» quarter=Q4/is_cumulative=True остаются от правила «год» при period_end=05-31 — предыдущее поведение #13, вне задачи.
Task 8: complete (commits 43ee753..f279157 + fixtures 8b9c22a, review clean after round 1)
Task 9: BASE f279157; implementer haiku dispatched
Task 9: implementer haiku DONE 55a7511; make check 2085 passed. Review sonnet: Needs fixes — Important T9.I1: test_inn_skips_auditor_block (test_header.py) не проверяет охрану: ИНН организации идёт выше аудитора, тест проходит и без min(last_row, auditor_from-1); Review Focus 2 не проверен.
Task 9: minor T9.1 (deferred): импорт приватной _FULL_CONFIDENCE в тесте. T9.2 (deferred): лишние кавычки в аннотации _report_date. T9.3 (deferred): фолбэк _organization без теста. T9.4 (deferred): okpo не ограничен границей аудитора.
Task 9: fix round 1/5 dispatched (resume implementer): T9.I1
Task 9: fix round 1/5 (1 addressed (а), 1 open — T9.I1(б): тест порядка «аудитор выше ИНН организации» стоит в обратном порядке и проходит без охраны; старый test_inn_skips_auditor_block оставлен как ложноположительный с вводящим в заблуждение docstring; commits 55a7511..27ffde4)
Task 9: fix round 2/5 dispatched (resume implementer)
Task 9: fix round 2/5 (0 addressed, 2 open — T9.I1(б) корректный тест «аудитор выше ИНН организации» (ожидание None, без охраны вернулся бы ИНН аудитора) либо честное объяснение; ложные утверждения в fix-отчёте (SHA pending, «ONLY scenario», число тестов, нет вывода make check); commits 27ffde4..e6696fa)
Task 9: fix round 3/5 dispatched (resume implementer)
Task 9: fix round 2 и 3 (round 2: 0 addressed; round 3: 2 addressed, 0 open — T9.I1(б) тест test_inn_not_taken_from_auditor_block_above_organization_inn, fix-отчёт исправлен; commits 27ffde4..cb0bd06)
Task 9: minor T9.5 (deferred): неточные номера строк в docstring нового теста; охрана при блоке аудитора выше ИНН организации теряет ИНН организации (None) — поведение зафиксировано тестом (O-5).
Task 9: complete (commits f279157..cb0bd06, review clean after round 3; make check 2086 passed)
Task 10: BASE cb0bd06; implementer haiku dispatched
Task 10: implementer haiku DONE 55b60f5; make check 2090 passed. Review sonnet: Needs fixes — T10.I1: порог дробной доли FRACTIONAL_SHARE=0.1 зашит в lines.py:37 (design D-6/решение 6: «число в словаре»; global constraint: словари — данные); T10.I2: нет теста границы 10 % (1 из 10 → warn, 1 из 11 → нет, numeric=0).
Task 10: minor T10.1 (deferred; снимается само при I1): float в сравнении доли. T10.2 (deferred): duplicates с повторами (код трижды → дважды) vs checks.duplicate_line_codes — уточнить в T12. T10.3 (deferred): merged_origin непоследовательно. T10.4 (deferred): тест test_lines_values_and_skips перегружен. T10.5 (deferred): нет теста минус-знака. T10.6 (deferred): мутационная проверка RED не показана.
Task 10: fix round 1/5 dispatched (resume implementer): T10.I1, T10.I2
Task 10: fix round 1/5 (2 addressed, 0 open — T10.I1, T10.I2; commits 55b60f5..aad6310)
Task 10: minor T10.7 (deferred → финальная волна): README правил (rules/README.md:17) и test_statement_rules.py не обновлены под fractional_share_percent (нет теста загрузки значения и валидатора 1..100).
Task 10: complete (commits cb0bd06..aad6310, review clean after round 1; make check 2093 passed)
Task 11: BASE aad6310; implementer haiku dispatched
Task 11: implementer haiku DONE? 7bcd324 (6 tests; в отчёте нет make check; в рабочем дереве остались НЕЗАКОММИЧЕННЫЕ правки statement_checks.yaml — 7 жёстких соотношений переведены в strict:false, чтобы пройти тесты плана). Review sonnet: Needs fixes — T11.I1 остаточный yaml ослабляет жёсткие соотношения (спека D-7/решение 7), тест test_tolerance_one_unit плана содержит 1100=100 без статей и падает на спеке; T11.I2 checks.py пропускает правило при отсутствующей цели; T11.I3 нулевой допуск для подстрок введён самовольно; T11.I4 расширение _RELATION/_TERM до 4–5 цифр ослабляет валидацию yaml (plan-mandated).
Ruling: R-6 — план внутренне противоречив (код плана без пропуска цели + тесты 1/4 плана, которые требуют пропуска): правило применяется в колонке, только если его ЦЕЛЬ присутствует среди строк (общая сумма формы), отсутствующие члены = 0 (спека D-7); правила для подстрок — если есть подстроки. Цена ошибки: форма, где пропущена сама итоговая строка при наличии членов, этим соотношением не ловится (1600 = 1700 ловится, пока присутствует 1600) (design #17).
Ruling: R-7 — yaml словаря НЕ ослабляется (жёсткие 1100…1500, 2100…2300 остаются strict:true по спеке D-7/решение 7); дефект плана исправляется в данных теста test_tolerance_one_unit (добавить статьи 1150=100, 1210=50, 1310=151). Цена ошибки: если владелец хочет мягкие компоненты — меняется одна строка yaml (design #18).
Ruling: R-8 — для подстрок общий допуск tolerance (±1), как в спеке; тест плана (1110=10, 6+3) исправляется данными (11101=6, 11102=2 → сумма 8, расхождение 2). Цена ошибки: чуть больше ложных мягких предупреждений на формах в тыс. руб. при нулевом допуске — не принято; при ±1 возможен пропуск расхождения в 1 (design #19).
Ruling: R-9 — расширение _RELATION/_TERM до 4–5 цифр в правой части принимается как plan-mandated, но явные правила из yaml ограничиваются четырёхзначными кодами валидатором загрузки (+тест); подстрочные — внутренние. Цена ошибки: возможность пятизначного кода в yaml — закрыта валидатором (design #20).
Task 11: fix round 1/5 dispatched (resume implementer)
Task 11: fix round 1/5 (3 addressed: T11.I1, I3, I4; 2 open — T11.I2: нет теста «цель отсутствует → нарушения нет» и реального мутационного доказательства; test_relation_holds_with_abs_terms пуст для цепочки 2200/2300: 2210/2220/2330/2350 не заданы; отчёт: мутация 3 не мутация, мутация 2 без вывода; commits 7bcd324..72e5656)
Task 11: fix round 2/5 dispatched (resume implementer)
Task 11: fix round 2/5 (2 addressed, 0 open — T11.I2, abs_terms цепочка, мутации в отчёте; commits 72e5656..b9e6e31)
Task 11: minor T11.1 (deferred): checks.py: is_subline = rule in subline_rules по равенству моделей (мёртвая ветка после удаления is_subline — проверить, что исчезла). T11.2 (deferred): fix-отчёт: устаревший раздел Git, номера строк. O-6: 1600=1700 при отсутствующем 1700 даёт нарушение на фрагментах (ожидаемо по манифесту: «только актив» → needs_check).
Task 11: complete (commits aad6310..b9e6e31, review clean after round 2; make check 2099 passed)
Task 12: BASE b9e6e31; implementer sonnet dispatched
Task 12: implementer sonnet DONE_WITH_CONCERNS 10b5bda; make check: 2 failed (golden s12, s14 — добавились документы форм), 2116 passed. Concerns: НПЗ даёт needs_check (1600=1700 расходится на 1.94/9.02/2.48 при допуске ±1; значения с копейками при «тыс. руб.»); данные тестов брифа не проходили find_code_column (сдвиг шапки, хвосты); header.py: StatementHeader(form_name=None); флаг dropped — продолжение без колонки кодов → needs_check книги; tests/synthetic s12/s14 ожидания.
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-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)
Task 13: BASE tabular-parser 6f0f05f, fixtures d0c543d; implementer haiku dispatched
Task 13: implementer haiku DONE d64ba71 (+fixtures ff39ad2: st01–st05 + README); make check 2135 passed (по заявлению). Review sonnet: Needs fixes — T13.I1 st02 подогнана под ответ (1200=(50) ломает 1600=1100+1200 → needs_check вместо done; комментарий «units=None warning» не соответствует коду); T13.I2 test_st02 не проверяет сценарии спеки (периоды по двум строкам заголовка, колонка без периода «Изменение, %» + предупреждение — по прогону ревьюера предупреждение НЕ выдаётся: возможен дефект парсера, 1210=-50, статус); T13.I3 st04/st01 слабые проверки (OsvDocument/типы/порядок; коды 1xxx не в INCOME и наоборот; статус done); T13.I4 пустая autouse-фикстура _require_synthetic. Отчёт task-13-report.md отсутствует.
Task 13: fix round 1/5 dispatched (resume implementer)
Task 13: fix round 1/5 (3 addressed: T13.I1, I3, I4; 1 open — T13.I2 предупреждение «колонка без периода пропущена: Изменение, %» на st02 не выдаётся: исполнитель оставил как OQ-T13-1 без расследования; commits d64ba71..fad0c10, fixtures f938255). make check 2135, test-fixtures 952 passed (по заявлению).
Ruling: R-12 — fix round 2 для T13.I2 отдан свежему исполнителю на sonnet (не резюм haiku): haiku отложил расследование дефекта парсера/данных; цена ошибки: нарушение «R≤3 — резюм исполнителя», стоимость — только лишний контекст.
Task 13: fix round 2/5 dispatched (sonnet): T13.I2
Task 13: fix round 2/5 (T13.I3, I4 addressed; парсерный дефект T13.I2 исправлен e7552dc columns.py::_upper_header_row; open: T13.I1 st02 всё ещё needs_check: 1100=200 при 1150=100/90 → нарушены 1100=Σ (кол.0, 1) и 1600=1100+1200 (кол.1); T13.I2(часть) тест st02 не проверяет status DONE/relations_failed==[] и 1210 внутри `if`; устаревший комментарий. Minor T13.3 (deferred): отрицательный тест для _upper_header_row — строка шапки документа непосредственно над датами; T13.4: EXPECTED_LINES_COUNT посреди файла; commits fad0c10..e7552dc)
Task 13: fix round 3/5 dispatched (resume sonnet fixer): T13.I1, T13.I2(часть)
Task 13: fix round 3/5 (3 addressed, 0 open — T13.I1, T13.I2(часть), минор _upper_header_row; commits e7552dc..4907935, fixtures b63c0a5). Re-review: All findings addressed. make check 2137 passed, make test-fixtures 952 passed, golden-check 113 без изменений.
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)