openspec: архив use-installed-statements-library (AURORA-1677)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-11-10 17:02:44 +04:00
parent 0e4af260aa
commit f2e0fd98f8
11 changed files with 69 additions and 7 deletions

View File

@ -443,7 +443,7 @@ RELATION_SOFT`, `severity = info`; `line_ids` — все строки `ok` ко
строк `detail` (ближайшая строка `ok` выше по `row_index`; нет такой — `null`, строка остаётся `detail`), записи строк `detail` (ближайшая строка `ok` выше по `row_index`; нет такой — `null`, строка остаётся `detail`), записи
`document_issue` видов `relation` / `soft` (заменяются целиком независимо от источника), статус. Относительные даты `document_issue` видов `relation` / `soft` (заменяются целиком независимо от источника), статус. Относительные даты
колонок (`period_kind`, `statement-normalization`) пересчитываются от даты отчёта после правки `header.report_date` и колонок (`period_kind`, `statement-normalization`) пересчитываются от даты отчёта после правки `header.report_date` и
`columns[].period_date`. Отличие `statements_version` задания от версии копии ядра — `document_issue` `columns[].period_date`. Отличие `statements_version` задания от версии установленной библиотеки ядра — `document_issue`
`STATEMENTS_VERSION_MISMATCH` (`info`); у задания без версии (`1.x`) запись не пишется. Записи `core` `STATEMENTS_VERSION_MISMATCH` (`info`); у задания без версии (`1.x`) запись не пишется. Записи `core`
`CODE_NOT_IN_DICTIONARY`, `CODE_NOT_IN_EDITION` (только четырёхзначные коды), `NAME_MISMATCH` и `CODE_NOT_IN_DICTIONARY`, `CODE_NOT_IN_EDITION` (только четырёхзначные коды), `NAME_MISMATCH` и
`STATEMENTS_VERSION_MISMATCH` пересчитываются заменой; `NAME_MISMATCH` не ставится строке с назначенным аналитиком кодом; `STATEMENTS_VERSION_MISMATCH` пересчитываются заменой; `NAME_MISMATCH` не ставится строке с назначенным аналитиком кодом;
@ -476,13 +476,21 @@ RELATION_SOFT`, `severity = info`; `line_ids` — все строки `ok` ко
- **THEN** запись `RELATION_FAILED` пересоздана с новыми `expected` / `actual`; `POST …/confirm` без акцепта — 409 - **THEN** запись `RELATION_FAILED` пересоздана с новыми `expected` / `actual`; `POST …/confirm` без акцепта — 409
`CHECKS_NOT_PASSED` `CHECKS_NOT_PASSED`
#### Scenario: Совпадение версии установленного дистрибутива
- **WHEN** форма из существующей фикстуры результата 2.0 принята с `service.statements_version`, равной версии установленной библиотеки без внутреннего `VERSION`
- **THEN** поле версии проходит валидацию и `STATEMENTS_VERSION_MISMATCH` не создаётся
#### Scenario: Разные версии библиотеки и сервиса
- **WHEN** та же форма принята с непустой версией сервиса, отличающейся от версии установленной библиотеки
- **THEN** создаётся `STATEMENTS_VERSION_MISMATCH` уровня `info` без ослабления валидации результата
### Requirement: Словари ядра и достройка шаблонных строк ### Requirement: Словари ядра и достройка шаблонных строк
Копия словаря §7 ядра (`api/rules/statement_checks.yaml`) SHALL быть удалена: проверки ядро считает копией пакета Копия словаря §7 ядра (`api/rules/statement_checks.yaml`) SHALL быть удалена: проверки ядро считает установленной библиотекой
`arm_statements`. `api/rules/statement_lines.yaml` SHALL оставаться только словарём имён (код → наименования по `arm_statements` (дистрибутив `pylib-ai-arm-statements`). `api/rules/statement_lines.yaml` SHALL оставаться только словарём имён (код → наименования по
редакциям): у кода может быть несколько имён (синонимы и законные повторы кода в бланке, Р-20), загрузчик повтор кода в редакциям): у кода может быть несколько имён (синонимы и законные повторы кода в бланке, Р-20), загрузчик повтор кода в
редакции MUST NOT запрещать; сверка наименования — с любым именем кода; шаблонная строка берёт первое имя. Порядок и редакции MUST NOT запрещать; сверка наименования — с любым именем кода; шаблонная строка берёт первое имя. Порядок и
состав редакций — из копии перечня кодов пакета (`code_orders.editions`); код словаря имён, которого нет в перечне своей состав редакций — из перечня кодов установленной библиотеки (`code_orders.editions`); код словаря имён, которого нет в перечне своей
редакции, — ошибка проверки (тест согласованности, `sync-statements --check`). В редакции `fsbu4` словарь имён SHALL быть редакции, — ошибка проверки (тест согласованности с установленной библиотекой). В редакции `fsbu4` словарь имён SHALL быть
дополнен вторыми именами законных повторов 1220 «НДС, начисленный по отгрузке», 1520 «Обязательство по аренде», 2410 дополнен вторыми именами законных повторов 1220 «НДС, начисленный по отгрузке», 1520 «Обязательство по аренде», 2410
«Налог при упрощенной системе налогообложения» (Р-20) и кодами печатной формы 1С 1105 «Гудвил», 1130 «Нематериальные «Налог при упрощенной системе налогообложения» (Р-20) и кодами печатной формы 1С 1105 «Гудвил», 1130 «Нематериальные
поисковые активы», 1140 «Материальные поисковые активы», 1530 «Доходы будущих периодов», 2460 «Прочее» (имена — по поисковые активы», 1140 «Материальные поисковые активы», 1530 «Доходы будущих периодов», 2460 «Прочее» (имена — по
@ -492,7 +500,7 @@ RELATION_SOFT`, `severity = info`; `line_ids` — все строки `ok` ко
молча. молча.
#### Scenario: Код словаря вне перечня #### Scenario: Код словаря вне перечня
- **WHEN** в `statement_lines.yaml` у редакции есть код, которого нет в перечне этой редакции копии пакета - **WHEN** в `statement_lines.yaml` у редакции есть код, которого нет в перечне этой редакции установленной библиотеки
- **THEN** проверка согласованности словаря с перечнем падает - **THEN** проверка согласованности словаря с перечнем падает
#### Scenario: Код есть только у строки unreadable #### Scenario: Код есть только у строки unreadable

View File

@ -8,7 +8,7 @@
### Requirement: Соотношения §7 по колонкам ### Requirement: Соотношения §7 по колонкам
Проверки SHALL считаться чистой функцией по текущим `financial_statement_value.amount` документа для каждой колонки Проверки SHALL считаться чистой функцией по текущим `financial_statement_value.amount` документа для каждой колонки
отдельно по словарю §7 копии пакета `arm_statements` (`statement-normalization`; своей копии словаря ядро не держит): отдельно по словарю §7 установленной библиотеки `arm_statements` (`statement-normalization`; своей копии словаря ядро не держит):
соотношение **посчитано**, если непуста цель (левая часть) или хотя бы один член (есть строка `ok` с кодом и непустой соотношение **посчитано**, если непуста цель (левая часть) или хотя бы один член (есть строка `ok` с кодом и непустой
суммой); если пусто всё — соотношение пропускается. В посчитанном соотношении отсутствующий код и пустая сумма в суммой); если пусто всё — соотношение пропускается. В посчитанном соотношении отсутствующий код и пустая сумма в
арифметике — 0, но пустая цель при непустых членах и непустая цель при пустых членах — нарушение (пустая цель даёт арифметике — 0, но пустая цель при непустых членах и непустая цель при пустых членах — нарушение (пустая цель даёт

View File

@ -0,0 +1,54 @@
# statement-library Specification
## Purpose
Поставка общей нормализации форм как устанавливаемой библиотеки с правилами и идентификатором версии, доступной ядру без встроенной копии исходников.
## Requirements
### Requirement: Установка локальной библиотеки
Команда `make install` SHALL устанавливать или переустанавливать дистрибутив `pylib-ai-arm-statements` в окружение backend `api/.venv` из соседнего репозитория `../pylib_ai_arm_statements`. Путь SHALL переопределяться через `STATEMENTS_DIR`. При отсутствии окружения команда SHALL создавать его на Python 3.11.
#### Scenario: Повторная установка после изменения библиотеки
- **WHEN** разработчик выполняет `make install` после изменения исходников или YAML-правил локальной библиотеки
- **THEN** backend получает обновлённую библиотеку, даже если номер версии дистрибутива не изменён
#### Scenario: Другой путь к исходникам
- **WHEN** разработчик выполняет `make install STATEMENTS_DIR=/tmp/local-statements`
- **THEN** библиотека устанавливается из указанного каталога в окружение backend
### Requirement: Подготовка окружения разработки
При установке `api/requirements.txt` команда `make venv` SHALL пропускать строки с префиксами `raisa_` и `pylib_ai`. Обработка `requirements-dev.txt` SHALL сохраняться: исключаются вложенные строки `-r`. После установки requirements локальная библиотека SHALL устанавливаться в окружение backend.
#### Scenario: Внутренний пакет не запрашивается из реестра
- **WHEN** requirements содержит `pylib_ai_arm_statements==0.1.1` и выполняется `make venv`
- **THEN** этот пакет не запрашивается из реестра по requirements и устанавливается из локального репозитория
### Requirement: Совместимость импортов и ресурсов
Установленная библиотека SHALL предоставлять импорт `arm_statements` и необходимые YAML-правила. Нормализация и загрузка стандартных правил MUST работать без каталога `api/arm_statements/` и без обращения к исходникам соседнего репозитория во время исполнения.
#### Scenario: Стандартные правила из установленного пакета
- **WHEN** установлен собранный дистрибутив и backend загружает стандартные правила
- **THEN** `statement_checks.yaml` и остальные необходимые YAML доступны внутри пакета; ошибка отсутствующего файла не возникает
### Requirement: Версия установленной библиотеки
Версия библиотеки SHALL определяться непустым стандартным маркером `VERSION`, а при его отсутствии или пустом содержимом — метаданными дистрибутива `pylib-ai-arm-statements`. Если оба источника недоступны, результат SHALL быть `None`. Явно переданный отсутствующий или пустой файл SHALL возвращать `None` без подстановки метаданных.
#### Scenario: Пакет без внутреннего VERSION
- **WHEN** у установленного дистрибутива версии `0.1.1` нет внутреннего `VERSION`
- **THEN** версия библиотеки равна `0.1.1`, а не `None`
#### Scenario: Приоритет маркера
- **WHEN** внутренний `VERSION` содержит непустой идентификатор, а метаданные содержат версию дистрибутива
- **THEN** возвращается идентификатор из `VERSION` без окружающих пробелов
#### Scenario: Явно указанный файл отсутствует
- **WHEN** вызывающий передаёт путь к отсутствующему файлу версии
- **THEN** возвращается `None`, даже если дистрибутив установлен
#### Scenario: Пустой стандартный маркер
- **WHEN** стандартный `VERSION` пуст, но метаданные дистрибутива доступны
- **THEN** возвращается версия дистрибутива
#### Scenario: Нет доступного идентификатора
- **WHEN** стандартного маркера и метаданных дистрибутива нет
- **THEN** возвращается `None`