12 KiB
Raw Blame History

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

  1. Локальная установка через 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 автоматически.

  2. Удаление vendored-кода и его проверок. api/arm_statements/ удаляется целиком вместе с тестами, rules и VERSION. statements-check и зависимость check-full от него удаляются. Pytest собирает tests, mypy проверяет src; Ruff считает только src first-party, поэтому импорты библиотеки перегруппированы в адаптерах и тестах. В mypy строгий override для копии заменён ignore_missing_imports, поскольку дистрибутив не поставляет py.typed. Тесты сервиса остаются; библиотечные тесты принадлежат библиотеке. Альтернатива сохранения двух копий допускает затенение установленного пакета локальной папкой.

  3. Версия через API библиотеки. require_statements_version продолжает вызывать statements_version(path) и запрещает старт при отсутствии версии. Меняются документация и RuntimeError: библиотека arm_statements без VERSION и версии пакета: выполните make install. VERSION сохраняет приоритет, метаданные дают fallback для установленного дистрибутива; прямое чтение метаданных в сервисе дублировало бы логику библиотеки. Тип поля контракта остаётся непустой строкой, JSON-схемы не редактируются.

  4. Именованный контекст 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 потребуется тот же именованный контекст; их конфигурация в этой задаче не менялась.

  5. Документация отражает библиотечную поставку. 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

  1. Подготовить checkout библиотеки версии 0.1.1; выполнить make venv либо make install в существующем окружении.
  2. Проверить, что arm_statements.__file__ указывает на site-packages, версия равна 0.1.1, default_rules() загружает данные, get_parser() создаёт BookParser.
  3. Выполнить lint, тесты адаптеров/версии и golden/fixtures-проверки на доступных реальных книгах. Перед релизом собрать и проверить контейнер с локальным контекстом.
  4. Для отката восстановить удалённую копию и прежние 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 повторно прошёл.