openspec: сквозная спека Среза 2b — контракт результата v1.2, §12, OQ
Proposal, design (состав v1.2: DISCLOSURE, statementDocument.checks, границы периода ОСВ; примеры; порядок раскатки потребители → производитель), дельта recognition-contract «Файл результата» v1.2, tasks. Refs #26 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
This commit is contained in:
parent
eaf4f5c2fd
commit
94846cbd4c
53
openspec/changes/slice-2b-statement-parser/design.md
Normal file
53
openspec/changes/slice-2b-statement-parser/design.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Design: Срез 2b (сквозное) — контракт v1.2, §12, OQ
|
||||
|
||||
## Context
|
||||
|
||||
Контракт `recognition-result.schema.json` v1.1: `statementDocument` рассчитан на OCR (поля `*_confidence`,
|
||||
`is_recognized`), `document_type ∈ {BALANCE, INCOME, OTHER}`, результатов проверок у форм нет (у `osvDocument` есть
|
||||
`checks`); `osvDocument.header` описывает период текстом, годом и кварталом, границы диапазона месяцев выразить нельзя
|
||||
(OQ-131). Правило версионирования: MINOR — необязательные поля и новые значения enum; потребители обновляют копии раньше
|
||||
производителя. Потребители копий: `tabular-parser` (тест идентичности в `make check`), `arm-core` (тест идентичности,
|
||||
pydantic-модели результата в `services/result_mapping.py`), `scan-gateway` (копия и модели).
|
||||
|
||||
## Decisions
|
||||
|
||||
### D-1. Состав v1.2
|
||||
- `$defs.statementDocument.properties.document_type.enum`: `["BALANCE", "INCOME", "DISCLOSURE", "OTHER"]`.
|
||||
- `$defs.statementDocument.properties.checks` (object, необязательное): `relations_failed` и `soft_relations_failed` —
|
||||
массивы объектов `{column_index: integer, relation: string, expected: money, actual: money}` (все четыре обязательны);
|
||||
`duplicate_line_codes` — массив строк. Описание: отсутствие объекта — «не проверялось» (OCR-путь), пустые массивы —
|
||||
«проверено, сошлось».
|
||||
- `$defs.osvDocument.properties.header.properties`: `period_start`, `period_end` — `["string", "null"]`, `format: date`;
|
||||
`is_from_year_start` — `["boolean", "null"]`. Описание: границы периода по шапке; для квартала/года — первое и последнее
|
||||
число; для диапазона месяцев — его границы; `is_from_year_start` = `period_start` — 1 января.
|
||||
- `title`, `description` схемы и `schema_version.description` — «1.2». `$comment` о версионировании не меняется.
|
||||
- `recognition-request.schema.json` и `recognition-result-message.schema.json` не меняются; `result_schema_version`
|
||||
в сообщении — строка, новых значений не требует.
|
||||
|
||||
### D-2. Примеры
|
||||
`result-statement-minimal.json` получает `checks: {relations_failed: [], soft_relations_failed: [], duplicate_line_codes: []}`
|
||||
и `schema_version: "1.2"`. Новый `result-statement-excel.json`: `service.name = tabular-parser`, три документа —
|
||||
`BALANCE` с `locator = "sheet:Бухгалтерский баланс. Лист 1,Бухгалтерский баланс. Лист 2"`, тремя колонками, строками
|
||||
1110/11101/1100/1600 и `checks` с одним нарушением в `soft_relations_failed`; `INCOME` на одном листе; `DISCLOSURE` без
|
||||
`columns`/`lines`; `status = needs_check` с предупреждением о единицах. `result-osv-minimal.json` — `period_start`,
|
||||
`period_end`, `is_from_year_start`. Все примеры валидируются тестами контракта в трёх сервисах.
|
||||
|
||||
### D-3. §12 — текст решений владельца
|
||||
§12 переписывается по пунктам 1–8 с сохранением нумерации и добавлением п. 9 «Склейка листов и страниц», п. 10 «Статус
|
||||
документа и книги», п. 11 «Что отложено» (запасной путь по именам, нормализация единиц, признак продолжения). Формулы §7
|
||||
остаются в §7; в §12 п. 7 — ссылка и правило «жёсткие/мягкие, допуск ±1, двойной расчёт знаков». Текст решений — из
|
||||
brainstorming 06.10.2026 (вопросы 2–6) и design дочернего change (D-2…D-8).
|
||||
|
||||
### D-4. Порядок раскатки
|
||||
docs (этот change) → bounded-PR в arm-core и scan-gateway «копия схемы v1.2 + модели, без логики» → tabular-parser
|
||||
(производитель 1.2) → fixtures (golden). Тест идентичности в сервисах пропускается только при недоступном docs, поэтому
|
||||
между мержем docs и мержем копий тесты сервисов на main падают; окно минимизируется одновременным открытием PR.
|
||||
|
||||
## Decisions made without discussion
|
||||
|
||||
| № | Дата | Решение | Обоснование | Цена ошибки |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 2026-10-06 | `checks` форм — отдельная структура, не переиспользование `osvDocument.checks` | у форм нарушения по колонкам и соотношениям, у ОСВ — по строкам | поле остаётся необязательным |
|
||||
| 2 | 2026-10-06 | `expected`/`actual` в нарушении — `money` (строка с двумя знаками), не число | единый тип денег контракта | смена типа — MAJOR, поэтому сразу строка |
|
||||
| 3 | 2026-10-06 | `is_from_year_start` — отдельное поле, `is_cumulative` не переопределяется | `is_cumulative` ядро уже трактует по OQ-02/124; новое поле не ломает семантику | два похожих поля |
|
||||
| 4 | 2026-10-06 | Пример `result-statement-excel.json` со статусом `needs_check` и `DISCLOSURE` | иллюстрирует все новые элементы одним файлом | нет |
|
||||
58
openspec/changes/slice-2b-statement-parser/proposal.md
Normal file
58
openspec/changes/slice-2b-statement-parser/proposal.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Proposal: Срез 2b (сквозное) — контракт результата v1.2, §12 ББ/ОФР из Excel, OQ
|
||||
|
||||
**Срез:** 2, подсрез 2b «парсер ББ/ОФР из Excel» (решение владельца 06.10.2026: только парсер и контракт; маппинг в ядро —
|
||||
Срез 3). **Репозиторий:** arm-ka-docs. **Issue:** RSHB/arm-ka-docs#26. **Дочерний change:**
|
||||
`tabular-parser/openspec/changes/slice-2b-statement-parser` (RSHB/arm-tabular-parser#14). Golden и синтетика —
|
||||
arm-ka-fixtures (отдельный PR). Копии схемы v1.2 — bounded-PR в arm-core и arm-scan-gateway.
|
||||
|
||||
## Why
|
||||
|
||||
§12 написан до появления реальных файлов. Пакет ДКБ 06.10.2026 принёс 15 форм в трёх раскладках (постраничные xls 1С,
|
||||
многолистовая книга ФСБУ 4/2023, `TDSheet`) и показал пять решений, которых в §12 нет: страницы одной формы в разных
|
||||
файлах, единицы «тыс. руб.» против значений с копейками, пятизначные подстроки «в том числе», соотношения §7 как данные,
|
||||
формы без колонки кодов. Контракту v1.1 не хватает структурного места для результатов проверок §7 и типа «расшифровка»
|
||||
(DBML `document_type.DISCLOSURE`), а ОСВ со скользящим периодом (OQ-131) — границ периода. Всё это MINOR.
|
||||
|
||||
## What Changes
|
||||
|
||||
- **Контракт v1.2** (`docs/contracts/recognition-result.schema.json`): `statementDocument.document_type` + `DISCLOSURE`;
|
||||
необязательный `statementDocument.checks` {`relations_failed[]`, `soft_relations_failed[]` — объекты `{column_index,
|
||||
relation, expected, actual}`; `duplicate_line_codes[]`}; необязательные `osvDocument.header.period_start`,
|
||||
`period_end` (date|null), `is_from_year_start` (boolean|null). `title`/`description` `schema_version` — «1.2».
|
||||
Примеры: `result-statement-minimal.json` дополняется `checks`; новый `result-statement-excel.json` (книга с `BALANCE` из
|
||||
нескольких листов, `INCOME`, `DISCLOSURE`); `result-osv-minimal.json` — новые поля шапки. Сообщение и запрос не меняются.
|
||||
Спека `recognition-contract`: «Файл результата» — v1.2.
|
||||
- **`05-domain-rules.md` §12**: решения владельца 06.10.2026 (вопросы 2–6 brainstorming) и уточнения по факту файлов:
|
||||
классификация листов и продолжений, титул «Бухгалтерская отчетность», склейка листов внутри книги и запрет склейки
|
||||
между файлами (страница без шапки → `needs_check`), единицы как есть + предупреждение, пятизначные подстроки как строки,
|
||||
§7 по четырёхзначным с допуском ±1 и двойным расчётом знаков, соотношения — данные `statement_checks.yaml`, отказ от
|
||||
запасного пути по именам в первой очереди, критерий `ok` документа, порядок документов книги. §7 — пометка, какие
|
||||
соотношения парсер считает жёсткими, какие мягкими (`ASSUMPTION(OQ-12)`).
|
||||
- **`06-test-data.md`**: раздел по `statements-xlsx/**` (раскладки, манифест ожиданий, golden `expected_statement_parse/`,
|
||||
синтетика `st01…st05`).
|
||||
- **`03-architecture.md`**: версия контракта 1.2, `BookParser` как реализация по умолчанию tabular-parser, порядок
|
||||
раскатки MINOR (потребители раньше производителя).
|
||||
- **`09-delivery-plan.md`**: Срез 2b — статус и объём по решению владельца; маппинг форм — Срез 3 (без изменений).
|
||||
- **`07-open-questions.md`**: новые OQ — единицы «тыс. руб.» против значений с копейками в 1С-выгрузках (кто и где
|
||||
приводит); форма без колонки кодов (словарь имён из шаблонов); страница-продолжение в отдельном файле (склейка в ядре,
|
||||
признак `is_continuation` в контракте); строка без кода с суммами в ОФР ФСБУ 4/2023; образец ФСБУ с «АКТИВ» и 1110 в
|
||||
одной строке. Статус OQ-131: границы периода в контракте v1.2, заполнение — парсер (#11 / 2b).
|
||||
- **`docs/dev/qa-guide.md` §6.7**: абзац про прогон парсера на формах.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Modified Capabilities
|
||||
- `recognition-contract`: «Файл результата» — v1.2 с `DISCLOSURE`, `statementDocument.checks`, границами периода ОСВ;
|
||||
«Версионирование контракта» — без изменений (MINOR по правилу).
|
||||
|
||||
## Impact
|
||||
|
||||
- Контракт: MINOR, обратно совместимо; копии обновляются в `tabular-parser` (дочерний change), `arm-core` и `scan-gateway`
|
||||
(bounded-PR: схема, примеры, pydantic-модели; логика не меняется — ядро по-прежнему маппит только `osvDocument`).
|
||||
Порядок merge: docs → arm-core, scan-gateway → tabular-parser → fixtures.
|
||||
- Таблицы DBML: нет (`DISCLOSURE` уже есть в `document_type`). Правила: §12 (решения владельца), §7 (пометки).
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Маппинг `statementDocument` в ядре и экран проверки форм — Срез 3.
|
||||
- Признак продолжения страницы в контракте, нормализация единиц, словарь имён строк — после появления потребителя/файла.
|
||||
@ -0,0 +1,39 @@
|
||||
# Spec Delta: recognition-contract
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Файл результата
|
||||
Файл результата SHALL соответствовать `docs/contracts/recognition-result.schema.json` v1.2: один файл (`stored_file`)
|
||||
→ один `job_id` → массив `documents` из `osvDocument` и/или `statementDocument`; денежные значения — строки
|
||||
`^-?\d+(\.\d{1,2})?$`; `confidence` — 0–100. Пустой массив `documents` допустим только при `status = error`.
|
||||
У строки `osvDocument.rows[]` SHALL быть необязательное поле `extra` — объект «заголовок колонки → строка или null» для
|
||||
колонок внутри таблицы, не сопоставленных с шестью суммами и ИНН (§1.2 «не терять»). У шапки `osvDocument.header` SHALL
|
||||
быть необязательные `period_start`, `period_end` (дата или null — границы периода по шапке; для квартала и года —
|
||||
первое и последнее число, для диапазона месяцев — его границы) и `is_from_year_start` (boolean или null; `is_cumulative`
|
||||
не переопределяется). `statementDocument.document_type` SHALL допускать `DISCLOSURE` (расшифровка или иная форма
|
||||
0710xxx: документ без `columns` и `lines`). У `statementDocument` SHALL быть необязательный объект `checks`:
|
||||
`relations_failed` и `soft_relations_failed` — массивы `{column_index, relation, expected, actual}` (нарушенные
|
||||
соотношения §7 по колонке; `expected`/`actual` — `money`), `duplicate_line_codes` — массив строк; отсутствие объекта
|
||||
означает «не проверялось», пустые массивы — «проверено, сошлось». Потребители, не знающие новых полей и значений,
|
||||
игнорируют их (MINOR). Производитель v1.2 пишет `schema_version = "1.2"`; файлы v1.0 и v1.1 остаются валидными.
|
||||
|
||||
#### Scenario: Результат валидируется примерами
|
||||
- **WHEN** CI сервиса запускает тесты контракта
|
||||
- **THEN** все файлы `docs/contracts/examples/result-*.json` проходят схему файла результата, а все
|
||||
`request-*.json` / `result-message-*.json` — схемы сообщений
|
||||
|
||||
#### Scenario: Лишняя колонка сохранена
|
||||
- **WHEN** в ОСВ между ИНН и суммами есть колонка «КПП»
|
||||
- **THEN** у строк контрагентов `extra = {"КПП": "<значение>"}`, файл проходит схему v1.2 и схему v1.0 (поле
|
||||
игнорируется)
|
||||
|
||||
#### Scenario: Форма из Excel с проверками
|
||||
- **WHEN** tabular-parser разобрал книгу с балансом на двух листах, ОФР и пояснениями (`examples/result-statement-excel.json`)
|
||||
- **THEN** файл проходит схему v1.2: `BALANCE` с `locator` из двух имён листов и `checks` с нарушением в
|
||||
`soft_relations_failed`, `INCOME` с пустыми массивами `checks`, `DISCLOSURE` без `columns`/`lines`; тот же файл
|
||||
без `checks` и с `document_type = OTHER` вместо `DISCLOSURE` проходит схему v1.1
|
||||
|
||||
#### Scenario: Границы периода ОСВ
|
||||
- **WHEN** в шапке ОСВ период «Октябрь 2024 г. – Сентябрь 2025 г.»
|
||||
- **THEN** `period_start = "2024-10-01"`, `period_end = "2025-09-30"`, `is_from_year_start = false`; файл проходит схему
|
||||
v1.2, а потребитель v1.1 читает его без ошибок
|
||||
17
openspec/changes/slice-2b-statement-parser/tasks.md
Normal file
17
openspec/changes/slice-2b-statement-parser/tasks.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Tasks: Срез 2b (сквозное) — контракт v1.2, §12, OQ (arm-ka-docs)
|
||||
|
||||
Задачи выполняются в ветке `feat/26-slice-2b-statement-parser`; детализация — в плане superpowers вместе с дочерним
|
||||
change tabular-parser.
|
||||
|
||||
- [ ] 1. Контракт v1.2: `docs/contracts/recognition-result.schema.json` — `DISCLOSURE`, `statementDocument.checks`,
|
||||
`osvDocument.header.period_start/period_end/is_from_year_start`, заголовок и описание «1.2» (design D-1); проверка
|
||||
схемы валидатором JSON Schema на всех примерах.
|
||||
- [ ] 2. Примеры: `result-statement-minimal.json` (+`checks`, «1.2»), новый `result-statement-excel.json`,
|
||||
`result-osv-minimal.json` (границы периода) (design D-2).
|
||||
- [ ] 3. Спека `openspec/specs/recognition-contract` синхронизируется из дельты при архивации; до этого — дельта в change.
|
||||
- [ ] 4. `05-domain-rules.md` §12 — решения владельца и уточнения (design D-3); §7 — пометка жёстких/мягких соотношений.
|
||||
- [ ] 5. `06-test-data.md` — раздел `statements-xlsx/**`, манифест, golden `expected_statement_parse/`, синтетика.
|
||||
- [ ] 6. `03-architecture.md` — контракт 1.2, `BookParser`, порядок раскатки MINOR; `09-delivery-plan.md` — Срез 2b.
|
||||
- [ ] 7. `07-open-questions.md` — новые OQ (единицы против копеек; форма без колонки кодов; страница-продолжение в
|
||||
отдельном файле; строка без кода с суммами в ОФР ФСБУ; образец ФСБУ «АКТИВ»+1110), статус OQ-131.
|
||||
- [ ] 8. `docs/dev/qa-guide.md` §6.7 — прогон парсера на формах; README `docs/contracts/` (если есть) — v1.2.
|
||||
Loading…
x
Reference in New Issue
Block a user