I-2: NULL у is_recognized не сомнение (P3-54); I-3: metrics.file_warnings при приёме 2.0 — единый
источник для пересчёта (P3-53, R-11); I-4/T4.4/T6.1: тесты правки, акцепта и веток приёма 2.0;
T4.2: now в checks_on_intake_1x; M-4: row_by_ref по принятым строкам; документация (M-5, M-6, M-7).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Удалены api/rules/statement_checks.yaml, load_check_rules, run_checks и правила соотношений; в
domain/statement_checks.py остались межформенная проверка 1370/2400 и subline_parents. Тест
test_name_dictionary_codes_in_code_orders сверяет справочник имён с перечнями редакций пакета.
CLAUDE.md и README.md: §7 — копия arm_statements, нарушения хранятся в document_issue. Решения P3-50…P3-52.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Модели и upgrade ревизии 0007_dbml_v5_19: пять enum'ов, колонки строк/значений/колонок/шапок форм,
document.file_ordinal (уникален в файле, уникальность типа только для не-форм), recognition_job.statements_version,
related_group.crm_id, таблица document_issue; заполнение по умолчанию (row_index, needs_review, header_source и др.).
delete_file_statements удаляет document_issue; make_document берёт следующий file_ordinal; маппер пока нумерует
документы по порядку создания. downgrade — заглушка (задача A2).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
I-1: ветка повторной публикации в _process_one записывает request_subject
(как первая публикация); тест test_republish_updates_request_subject.
M-1: примеры /healthcheck в README (ядро: три subject'а; tabular-parser: два).
M-3: docstring'и и логи не выдают умолчание за фактический subject.
M-5: CLAUDE.md — subject'ы задаются OPENBAO__NATS__NATS_*_SUBJECT.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Настройка CONSOLIDATION_PERIOD_FROM_VERSION (по умолчанию false; в контуре —
OPENBAO__APP__CONSOLIDATION_PERIOD_FROM_VERSION): ОСВ, загруженная в консолидацию
(stored_file.consolidation_id), считается нарастающей за год и квартал консолидации,
какой бы период ни стоял в шапке. Нужен для тестов на произвольных ОСВ: без него ОСВ
за 1 кв. 2025 в консолидации 2026 Q1 молча не привязывается и свод пуст.
- domain/version_period.py: представление документа с периодом версии (первичка не меняется)
- consolidation_documents.for_consolidation: единая точка подмены; её используют привязка
(fits, ключ R-1, bind_confirmed, хуки подтверждения и маппинга), свод, чек-лист,
колонка «ОСВ» периметра (osv_accounts)
- ББ/ОФР и файлы с рабочего стола режим не затрагивает; склейки кварталов в режиме нет
- тесты: unit на чистые функции, интеграционные — сценарий 2025 Q1 → 2026 Q1 с режимом
и без, файл вне консолидации, чек-лист и карточка, подхват «один слот на счёт»
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DB_SCHEMA (по умолчанию dkb, валидация идентификатора) читают models/base.py (SCHEMA), db/db.py (search_path),
alembic/env.py и миграции 0001-0005 (SCHEMA и строковые FK f"{SCHEMA}.x.id" вместо литералов). В контуре -
OPENBAO__APP__DB_SCHEMA. Офлайн-SQL `alembic upgrade head --sql` при значении по умолчанию совпадает побайтно.
Тесты: валидация настройки, миграции и сессия приложения в схеме dkb_alt; .env.example/.env.test/README/CLAUDE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
- модели LegalEntity.kpp / LegalEntityHistory.kpp (последней колонкой), миграция 0005_dbml_v5_17 (upgrade/downgrade);
- domain/kpp.py: 9 символов (4 цифры, 2 цифры/латинские A-Z, 3 цифры), у ИП запрещён, иначе 422 INVALID_KPP;
- схемы Create/Update/Out/Detail/HistoryOut, PATCH пишет снимок history и аудит before/after с kpp, поиск q по КПП;
- импорт справочника: необязательная колонка КПП (синоним kpp), код INVALID_KPP, update обновляет непустой КПП;
- dev-seed: необязательный ключ kpp (значений в данных нет, не выдумываем);
- сверка с DBML, Makefile, README, CLAUDE.md, openspec/config.yaml — на v5.17.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
- .env.example: UPLOAD_MAX_BYTES — больший файл уходит в rejected[] с кодом
FILE_TOO_LARGE, ответ 201/422, а не 413 (M-2).
- README «Ограничения»: размер multipart-запроса и число файлов приложением не
ограничены — лимит ingress платформы (M-4); индексы osv_entry — OQ-117 (I-1);
S3 — OQ-22 и OQ-111 (T12.3); автозамена частью документов — OQ-115 (T12.2);
удаление ставит expires_at только объектам папок файла (M-3).
- README/CLAUDE.md: цикл маппинга запускается при NATS_ENABLED и подключённом S3;
строка NATS_ENABLED в таблице настроек перечисляет цикл маппинга (T12.4).
- tasks.md 3.1: сигнатура counterparty_check(header, owner_inn,
owner_names_normalized) (T12.5).
- design.md: №51 (R-24, I-1 — решение человека, OQ-117), №52 (R-25, fix wave
M-1/M-3/T7.2).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
- OsvDataType.NU после BU, DBML_VERSION = 5.15, Makefile/dbml_parity/docstring'и на data-model-v5.15.dbml;
- миграция 0003_dbml_v5_15: ADD VALUE 'NU' AFTER 'BU' + lower(app_user.email); downgrade пересоздаёт osv_data_type
(регистр email не возвращается);
- email хранится в нижнем регистре: users_admin.create_user и seed (_apply_users); с UNIQUE по строчному email гонка
создания в другом регистре теперь ловится индексом (тест test_api_constraint_races обновлён);
- тесты: enum NU, откат на шаг, lower email на миграции, seed/админка, вставка NU, фиктивная v5.16.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
Формулировка уточнена в докстрингах `services/session_audit.py` и
`api/dependencies/auth.py`, README «Безопасность dev-режима» и CLAUDE.md; тест
событий входа дополнен запросом со схемой Basic.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
При непустой `role_permission` вставляются пары, у которых роль или право
вставлены этим же прогоном (`_upsert` возвращает вставленные ключи): их
администратор снять не мог. Прочие пары по-прежнему не трогаются — снятые
права не возвращаются. Убрана мёртвая ветка `unchanged` (R-9): при пустой
таблице совпадений быть не может, при заполненной сверка не нужна.
Тесты: новое право и новая роль во временном seed-каталоге → повторный seed
выдаёт только их пары, снятая связь не возвращается; администратор снял все
связи → матрица заливается заново. README, CLAUDE.md, комментарий
`role_permissions.yaml` и докстринг `seed.py` уточнены.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
`_apply_role_permissions` (`scripts/seed_lib/apply.py`) загружает матрицу из
`role_permissions.yaml` только при пустой `role_permission`; иначе шаг
пропускается целиком с причиной в отчёте (`TableStat.skipped_reason`,
«role_permission: пропущено — …»). Права, снятые администратором, не
возвращаются; `role` и `permission` по-прежнему upsert'ятся.
Тесты: повторный прогон — «пропущено», матрица та же; снятая связь после
повторного seed не возвращается. README «Администрирование» и раздел seed
переписаны под новое поведение.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
Раздел SESSION, object_type app_user, IP и user-agent запроса
(`services/session_audit.py`):
- LOGIN — выдача dev-токена (в транзакции запроса) и первый успешный
`current_user` пользователя после старта процесса (`SessionAudit.logged_in`,
в памяти процесса; параллельные первые запросы — одно событие);
- LOGIN_FAILED — 401 (токен не принят: user_id пуст, причина без токена) и 403
аутентификации (не зарегистрирован / отключён / неоднозначен: email в
description, user_id — если найден). `AuthenticationFailedError` (подкласс
HTTPException) обрабатывается после отката транзакции запроса, запись — в
отдельной транзакции `session_transaction`, поэтому остаётся в журнале.
Без заголовка Authorization и 403 «недостаточно прав» — не события входа;
ошибка записи аудита входа ответ не меняет.
Тесты: `test_login_audit.py` (в т.ч. фиксация при откате запроса на
`committed_app`); счётчики следов импорта не учитывают события SESSION.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
CLI `python -m scripts.seed --dev` сверяется с `DEBUG` (`check_dev_allowed`) до
чтения seed и подключения к БД; при `DEBUG=false` — код возврата 2 и сообщение
«--dev доступен только при DEBUG=true (dev-пользователи не для прода)».
`run_seed(session, dev=True)` защиты не имеет (её вызывают тесты).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
Строка «Контракты» перечисляет три реальные схемы recognition-* и копии в api/contracts/; ex-payload-v1 помечен
как будущий (Срез 7). В раскладке — src/api/endpoints. В docstring app.py убрано утверждение, что middleware
РАИСА подключается при DEBUG=False (пакет лишь условно импортируется).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
CLAUDE.md: цели make из корня, NATS_ENABLED vs DEBUG, обмен recognition_job, аудит, аутентификация, seed,
сверка ORM-DBML, тесты; Dockerfile для dev и check-full; skip reason у fixtures.
tasks.md/plan: required_document_rule в audit_ex.py (R-4); spec data-model: 43 таблицы модели + alembic_version.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
handle_message(msg, *, session_factory, mapper, now): разбор конверта по контракту v1.0, одна короткая транзакция
с SELECT … FOR UPDATE (ждёт блокировку публикатора/вахтёра); ack published → processing; результат — дедуп по
result_msg_id, финальные статусы (R-22) не трогаются, регистрация s3_object (results), слияние метрик с сохранением
republish_count. Подписка app.py получает handler с фабрикой сессий и NoopMapper; шаблонный core/nats_callback.py
удалён (R-3). audit_event не пишется (R-7).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Обмен с ядром на core NATS: подписка queue group, ack status=processing сразу по получении, process-local
LRU job_id против повторных запросов, публикация результата с повторами; удалены durable consumer / max_deliver /
ack_wait. Dockerfile python:3.11-slim; make check / make check-full вместо CI; raisa_* фильтруются при
dev-установке. Обновлены proposal, design (решения без обсуждения), specs, tasks, CLAUDE.md, openspec/config.yaml.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Срез 0 (issue #1): раздел «Соглашения шаблона» (что оставлено от шаблона команды, что
вырезается, что добавляется); change openspec/changes/slice-0-skeleton — proposal, design
с таблицей «Decisions made without discussion», спеки и tasks; в openspec/config.yaml
строки с двоеточием взяты в кавычки (YAML разбирал их как словари).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>