12 KiB
Design
Context
См. proposal.md, раздел Why. Переход уже отражён в staged-изменениях сервиса; этот change документирует выполненную работу и оставшиеся проверки. Основные спецификации после отмены предыдущих правок по-прежнему описывают копию исходников. Их изменение вынесено в delta-файлы этого change.
Пример локальной установки — ../arm-core/Makefile. Дистрибутив находится в ../pylib_ai_arm_statements: имя установки pylib-ai-arm-statements, версия 0.1.1, имя импорта arm_statements. Его API statements_version(path) читает VERSION, затем метаданные пакета; явный путь используется тестами и не включает fallback. default_rules() загружает словари из установленной библиотеки.
Goals / Non-Goals
Goals: единый установленный источник кода и словарей для разработки и контейнера; повторная установка локальных изменений без смены версии; проверка версии при старте; сохранение адаптеров и проверок сервиса.
Non-Goals: редактирование исходников библиотеки, библиотечных тестов, внешнего CI/Compose и канонических схем. Денежные расчёты остаются Decimal, единицы (рубли / тысячи рублей) не меняются. ORM и консолидация не затрагиваются.
Decisions
-
Локальная установка через uv.
make venvфильтрует^(raisa_|pylib_ai)изapi/requirements.txt, устанавливает оставшиеся зависимости и dev-инструменты, затем ставитSTATEMENTS_DIR.make installсоздаёт окружение Python 3.11 при необходимости и использует--reinstall-package pylib-ai-arm-statements, чтобы подтянуть изменения при прежней версии. Путь по умолчанию совпадает с соседним checkout; переопределение поддерживает другую раскладку workspace. Альтернативы: editable-установка делает окружение зависимым от живых исходников; копирование возвращает проблему синхронизации; индекс недоступен для этого пакета. Pin в requirements документирует ожидаемую версию, но локальная установка не проверяет совпадение VERSION с pin автоматически. -
Удаление vendored-кода и его проверок.
api/arm_statements/удаляется целиком вместе с тестами, rules и VERSION.statements-checkи зависимостьcheck-fullот него удаляются. Pytest собираетtests, mypy проверяетsrc; Ruff считает толькоsrcfirst-party, поэтому импорты библиотеки перегруппированы в адаптерах и тестах. В mypy строгий override для копии заменёнignore_missing_imports, поскольку дистрибутив не поставляетpy.typed. Тесты сервиса остаются; библиотечные тесты принадлежат библиотеке. Альтернатива сохранения двух копий допускает затенение установленного пакета локальной папкой. -
Версия через API библиотеки.
require_statements_versionпродолжает вызыватьstatements_version(path)и запрещает старт при отсутствии версии. Меняются документация и RuntimeError:библиотека arm_statements без VERSION и версии пакета: выполните make install. VERSION сохраняет приоритет, метаданные дают fallback для установленного дистрибутива; прямое чтение метаданных в сервисе дублировало бы логику библиотеки. Тип поля контракта остаётся непустой строкой, JSON-схемы не редактируются. -
Именованный контекст BuildKit.
make docker-buildпередаёт--build-context statements="$(STATEMENTS_DIR)". Dockerfile подключает его через временный bind mount на шаге RUN и устанавливает/tmp/statementsвместе с отфильтрованными requirements.rwнужен сборочным инструментам для временных файлов; изменения mount не записываются обратно на хост и не становятся содержимым образа. Установленный пакет и его package data остаются в образе. Альтернатива расширения основного контекста на весь workspace меняет правила COPY и состав контекста; копирование checkout в слой добавляет ненужные исходники. Прямым вызовам Docker, внешним CI и Compose потребуется тот же именованный контекст; их конфигурация в этой задаче не менялась. -
Документация отражает библиотечную поставку. README, CLAUDE.md,
api/rules/README.md, комментарии в requirements-dev, проверке версии, тесте worker и моделиServiceобновлены. Архивные OpenSpec change и копии JSON-схем не переписываются. Внешнее описание поля как коммита требует согласования отдельным change в docs.
Risks / Trade-offs
- [Нет локального checkout или неверный STATEMENTS_DIR] → установка завершается ошибкой; путь и команда переустановки описаны в README.
- [Отличие локальной версии от pin] → перед сборкой проверять метаданные дистрибутива и
statements_version(); при Docker-сборке pip автоматически проверяет соответствие локальной версии pin из requirements. - [Версия 0.1.1 не идентифицирует локальные изменения исходников] → переустановка принудительная, воспроизводимый релиз требует дисциплины версий библиотеки; Git SHA больше не является обязательным форматом поля.
- [Нет BuildKit или не передан именованный контекст] → использовать
make docker-build; в других системах сборки явно передавать контекст. - [Нет маркера типов у библиотеки] → mypy проверяет код сервиса, поведение интеграции подтверждают тесты адаптеров.
- [Описание JSON-схемы ещё говорит о коммите] → не нарушать идентичность копии контракта; согласовать описание в docs отдельно.
Migration Plan
- Подготовить checkout библиотеки версии 0.1.1; выполнить
make venvлибоmake installв существующем окружении. - Проверить, что
arm_statements.__file__указывает на site-packages, версия равна 0.1.1,default_rules()загружает данные,get_parser()создаёт BookParser. - Выполнить lint, тесты адаптеров/версии и golden/fixtures-проверки на доступных реальных книгах. Перед релизом собрать и проверить контейнер с локальным контекстом.
- Для отката восстановить удалённую копию и прежние Makefile/Dockerfile/конфиги одним откатом изменения; не оставлять обе модели поставки одновременно.
Validation Evidence
Результаты предыдущего выполнения в этой сессии (не повторная проверка в рамках proposal):
- Локальная установка завершилась:
pylib-ai-arm-statements==0.1.1; импорт из site-packages, библиотека сообщает0.1.1, словари загружаются, создаётся BookParser. make lintпрошёл (Ruff, format, mypy).tests/unit/parser: 1206 passed, 5 skipped; три теста проверки версии/ошибки загрузки словарей вtest_worker.pyпрошли.- Полный unit-прогон остановлен после зависания на worker-тестах; успешный полный прогон не заявляется. Для запуска тестов потребовалось переопределить некорректное внешнее значение DEBUG через
DEBUG=false. - Docker-сборка не проверена: доступ к
/var/run/docker.sockзапрещён. Реальные fixtures/golden и интеграционные NATS/S3-проверки отдельно не выполнялись.
Проверки при продолжении apply (24.10.2026)
-
Реальные формы: 27 passed; сравнение форм с golden-снимками: 27 passed. Снимки не перезаписывались.
-
make venvи повторныйmake installс абсолютным STATEMENTS_DIR прошли; библиотека 0.1.1 импортируется из site-packages. -
make test-integrationвне песочницы: 10 passed, включая реальные формы и версию библиотеки в результате. -
Полный unit-прогон вне песочницы: 1733 passed, 1 failed за 4.78 s. В песочнице worker-тесты зависают; вне неё это не воспроизводится.
-
Единственная ошибка unit-прогона — идентичность
api/contracts/recognition-result.schema.jsonактуальному файлу docs: в docs уже изменены два текстовых описания (библиотека и источник её версии), структура схемы прежняя. Синхронизация копии ожидает решения пользователя по границе задачи. -
Docker-сборка завершилась успешно; запуск образа с
--network noneбез mount исходников подтвердил импорт из site-packages, версию 0.1.1 и загрузку словарей.make lintповторно прошёл.