Копия исправления arm-web #22 (контур разворачивается из web/). Обычная сборка pdfjs-dist 5.7 в воркере
вызывает Uint8Array.prototype.toHex (Chromium 140+), в Яндекс Браузере getDocument падает
«a.toHex is not a function». PdfPages берёт модуль и воркер из pdfjs-dist/legacy/build через
widgets/DocumentReview/pdfjs.ts; регрессионный тест открывает PDF без Uint8Array.prototype.toHex.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Решение владельца 09.10.2026. Парсер — по-прежнему 5 мин. Note DBML
«OCR — 5 мин» не меняется до следующей версии модели (OQ-159).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Формы «Добавить/Изменить юридическое лицо» (макет 51-02, 79) отправляют всё
одним запросом. POST/PATCH /directories/legal-entities принимают `aliases`,
`gsk_id`, `gsz_id` и применяют их в той же транзакции, что и поля ЮЛ.
- POST: алиасы и членства создаются вместе с ЮЛ; ошибка откатывает всё.
- PATCH: `aliases` — итоговый набор (сверка по normalized_alias; удаление —
с правом DIRECTORY_DELETE, иначе 403), `gsk_id`/`gsz_id` — итоговые группы
(`null` — выйти, другая — сменить); не переданное поле не меняется.
- Новая ошибка 422 WRONG_GROUP_KIND; дубль в списке — 409 ALIAS_EXISTS.
- Ответ POST и PATCH — LegalEntityDetail (надмножество LegalEntityOut).
- Логика ручек алиасов и состава ГСК/ГСЗ вынесена в функции модулей
(add_alias/remove_alias, add_membership/close_membership) — форма и ручки
ведут себя одинаково; PermissionDeniedError — единый 403 «недостаточно прав».
- Спека directories-api и README обновлены.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Спеки documents-api и statement-checks обновлены дельтой change'а; change перенесён в
openspec/changes/archive/2026-10-09-statement-template-lines/. Реализация — PR #81.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
M-9: design.md и proposal.md приведены к коду (достройка - _lines_out в
schemas/statements.py, справочник без valid_from/valid_until, ленивая
загрузка с ручными проверками); добавлены R-12 и R-13. T5.1/M-8: сигнатура
PATCH values и обратные кавычки в таблице ошибок README.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Правка arm-web 9e89b9f перенесена в arm-core/web: id и origin у строк и ячеек
формы, ключ достроенной строки code-<код>, отправка line_code, раскладка
formLayout. Без неё встроенный фронт отправлял бы line_id "null" (I-1, R-12).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
statement_amounts не отдаёт проверкам строки с line_code_original_value IS NULL,
у которых все суммы пустые; заполненная хотя бы в одной колонке строка
проверяется по всем колонкам.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CellPatch адресует ячейку ровно одним из line_id / line_code. Строка справочника
редакции, которой нет в форме, создаётся при первой непустой правке
(line_code_original_value = NULL — признак «не из источника»); отсутствующая
ячейка существующей строки тоже создаётся. Адресация (колонка, строка, код)
проверяется целиком до первой вставки, две ячейки новой строки делят одну
строку, повтор line_code после создания даёт 422 UNKNOWN_CELL. Аудит — одно
RECOGNIZED_DATA_EDIT на запрос, у созданной ячейки before = null.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
GET …/statement добавляет строки справочника редакции, которых нет в форме
(id = null, origin = template), и недостающие ячейки существующих строк
(id = null, все значения пусты). В БД ничего не пишется. Добавлено поле
LineOut.origin (source | template).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Относительный `git -C arm-core` из корня workspace указывал на main-checkout
(O-1 первого запуска контроллера).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qoydUVv8g1qHxc123u2RR
Спека: достройка формы по справочнику строк редакции в GET …/statement,
создание строки и ячейки при первой правке по line_code, пустые шаблонные
строки вне проверок §7 и статуса.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qoydUVv8g1qHxc123u2RR
Решения владельца 08.10.2026:
- отмена П-1: «Осталось N» (`unmapped_total`) и `?unmapped=true` — строки без ЮЛ после резолва и без ИНН из файла;
строка с ИНН, которого нет в справочнике, сопоставления не требует (`domain.needs_mapping`);
- `ConsolidatedRowOut.counterparty_entity_inn` — ИНН сопоставленного ЮЛ справочника (П-8): фронту — «таблетка»
с ИНН и пересопоставление у строк, сопоставленных без ИНН в файле.
Фикстуры РБ 2024 Q3: unmapped_total 1379 → 1260. Спека consolidated-osv и README обновлены.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
В LegalEntityOut (а значит и LegalEntityDetail) добавлено company_group_name: текущее имя ГК company_group_id,
архивной тоже; у монозаёмщика null. Есть во всех ответах /directories/legal-entities: список, карточка, POST,
PATCH, move, withdraw; в снимках истории нет. Имена набора ЮЛ подгружаются одним батч-запросом
(repositories.directories.company_group_names_by_ids), число запросов списка от числа строк не зависит.
Спека directories-api и README дополнены.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
Условия подтверждения формы ББ/ОФР вынесены в statement_hard_failures и form_confirmable
(модульные функции services/statements.py); ручной путь (documents._check_statement) использует
тот же statement_hard_failures и отвечает 409. Тест с нарушением строгого соотношения на 2200
(соотношения с 2400 в словаре мягкие).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 задач: хук подтверждения с автором перехода, form_confirmable, auto_confirm,
вызов в маппинге, удаление файла, документация arm-core, правило и OQ-157 в docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
setup_logger() с diagnose=False существовал, но не вызывался: работал
обработчик loguru по умолчанию (diagnose=True), и трейсбек любого
залогированного исключения содержал значения локальных переменных.
Теперь src/app.py вызывает setup_logger при импорте, как tabular-parser.
Регрессионный тест в отдельном процессе: исключение с локальной
переменной логируется с трейсбеком, но без её значения.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
Proposal, design (D-1…D-6, решения без обсуждения №1–7) и дельты osv-result-mapping,
primary-files, audit-trail: чистый документ при маппинге сразу CONFIRMED (система,
confirmed_by NULL; переход версии — от загрузившего), удаление автоподтверждённых
файлов до DATA_CORRECTION включительно. Решение владельца 08.10.2026, ТЗ 03_9 п. 4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Замена остаётся на уровне файла (§9.5 п. 3, OQ-115), но если у заменённого файла есть
документы, ключа которых (document_type, osv_account_code, год, квартал) нет среди
документов нового файла, в metrics.mapping_warnings задания нового файла добавляется
предупреждение (OQ-154): имя и версия заменённого файла, выпавшие документы (тип, счёт,
период, статус, в т. ч. CONFIRMED) и версии консолидации, с которых сняты привязки
выпавших документов. Поведение замены, FILE_REPLACE и статусы документов не меняются.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
CounterpartyIndex.resolve: порядок шагов ИНН -> точное имя -> алиас -> нормализованное
имя (OQ-128, §3 п. 4). Алиас уникален (ALIAS_TAKEN), поэтому владелец алиаса берётся
с match_kind = ALIAS, даже если есть ЮЛ-тёзки по нормализованному имени; NULL остаётся
при нескольких совпадениях только по имени. Правило общее для маппинга (Срез 2c) и
дорезолва свода на чтение (§3 п. 7).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2