From 55f06e9458619f1ab6300ba505d915d0c452be60 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sat, 7 Nov 2026 03:56:47 +0400 Subject: [PATCH] =?UTF-8?q?fix(#202):=20=D1=81=D1=85=D0=B5=D0=BC=D0=B0=20q?= =?UTF-8?q?uality-facts=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=20contracts/metrics/=20(=D0=BD=D0=B5=20?= =?UTF-8?q?=D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D1=82=20=D0=BA=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=B2=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D1=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- contracts/{ => metrics}/quality-facts.schema.json | 0 docs/superpowers/plans/2026-11-05-quality-metrics-dbml.md | 8 ++++---- model/data-model-v5.25.dbml | 4 ++-- openspec/changes/quality-metrics/design.md | 3 ++- openspec/changes/quality-metrics/proposal.md | 2 +- .../quality-metrics/specs/quality-metrics-model/spec.md | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) rename contracts/{ => metrics}/quality-facts.schema.json (100%) diff --git a/contracts/quality-facts.schema.json b/contracts/metrics/quality-facts.schema.json similarity index 100% rename from contracts/quality-facts.schema.json rename to contracts/metrics/quality-facts.schema.json diff --git a/docs/superpowers/plans/2026-11-05-quality-metrics-dbml.md b/docs/superpowers/plans/2026-11-05-quality-metrics-dbml.md index fdd440d..779f770 100644 --- a/docs/superpowers/plans/2026-11-05-quality-metrics-dbml.md +++ b/docs/superpowers/plans/2026-11-05-quality-metrics-dbml.md @@ -248,10 +248,10 @@ git commit -m "docs(#202): §14 — счёт и атрибуция метрик --- -### Task 4: `docs/contracts/quality-facts.schema.json` — контракт payload +### Task 4: `docs/contracts/metrics/quality-facts.schema.json` — контракт payload **Files:** -- Create: `contracts/quality-facts.schema.json` +- Create: `contracts/metrics/quality-facts.schema.json` **Interfaces:** - Consumes: имена и смысл полей `payload` из Task 1 (`quality_intake_fact.payload`, `quality_outcome_fact.payload`). @@ -268,13 +268,13 @@ raw_line_codes для intake; + fixes[] для outcome; у OSV — `osv_warnings - [ ] **Step 2: Проверить, что файл — валидный JSON Schema** -Run: `python3 -c "import json, jsonschema; jsonschema.Draft202012Validator.check_schema(json.load(open('contracts/quality-facts.schema.json')))"` +Run: `python3 -c "import json, jsonschema; jsonschema.Draft202012Validator.check_schema(json.load(open('contracts/metrics/quality-facts.schema.json')))"` Expected: без вывода и без исключения (код возврата 0). - [ ] **Step 3: Коммит** ```bash -git add contracts/quality-facts.schema.json +git add contracts/metrics/quality-facts.schema.json git commit -m "docs(#202): контракт payload фактов качества первички" ``` diff --git a/model/data-model-v5.25.dbml b/model/data-model-v5.25.dbml index 627ced6..0933e46 100644 --- a/model/data-model-v5.25.dbml +++ b/model/data-model-v5.25.dbml @@ -1664,7 +1664,7 @@ Table quality_intake_fact { raw_s3_key varchar [note: 'PDF; NULL для Excel'] result_s3_key varchar upload_s3_key varchar - payload jsonb [not null, note: 'снимок «как распознано»: header/lines/values/issues (contracts/quality-facts.schema.json#intake-payload). Для OSV — БЕЗ построчного снимка lines/values, только счётчики выше и osv_warnings[] — правок сумм ОСВ в ядре нет'] + payload jsonb [not null, note: 'снимок «как распознано»: header/lines/values/issues (contracts/metrics/quality-facts.schema.json#intake-payload). Для OSV — БЕЗ построчного снимка lines/values, только счётчики выше и osv_warnings[] — правок сумм ОСВ в ядре нет'] payload_schema_version varchar Indexes { (document_id) [unique] @@ -1693,7 +1693,7 @@ Table quality_outcome_fact { issue_count_at_outcome int [not null, default: 0] report_date date [note: 'подтверждённая отчётная дата'] confirmed_by uuid [note: 'для агрегатов не используется'] - payload jsonb [not null, note: 'подтверждённый результат + fixes[] (contracts/quality-facts.schema.json#outcome-payload)'] + payload jsonb [not null, note: 'подтверждённый результат + fixes[] (contracts/metrics/quality-facts.schema.json#outcome-payload)'] payload_schema_version varchar Indexes { (document_id, outcome_at) diff --git a/openspec/changes/quality-metrics/design.md b/openspec/changes/quality-metrics/design.md index a1f40dd..ccaf0f8 100644 --- a/openspec/changes/quality-metrics/design.md +++ b/openspec/changes/quality-metrics/design.md @@ -142,7 +142,7 @@ Enum quality_failure_kind { - `recognition_job.raw_s3_object_id uuid [ref: > s3_object.id]` — заменяет прежнюю заметку «сырой ответ в БД не регистрируется» (v5.13); заполняется при приёме результата image pipeline. -## 2. Контракт `docs/contracts/quality-facts.schema.json` +## 2. Контракт `docs/contracts/metrics/quality-facts.schema.json` JSON Schema (Draft 2020-12), три подсхемы с `$id` `intake-payload`, `outcome-payload`, `failure-fact` (у failure payload нет — все поля плоские). Описывает только `payload` интейка и исхода: @@ -178,3 +178,4 @@ NATS-контракта (`request-`/`result-message-`/`result-` префиксы | 05.11.2026 | Атрибуция правок — 2 источника (service/ours), не 3: «документ клиента» — свойство исхода, не правки (см. §5 исходного design: таблица даёт только «сервис» или «наш разбор») | в design arm-core таблица §5 бинарна; «документ клиента» в §6 — отдельное правило по checks_accepted | лишний enum-источник правки, если окажется нужен позже | | 05.11.2026 | `quality-facts.schema.json` не подключается к `scripts/validate_contracts.py` | скрипт — для NATS wire-контракта с дедупом/версией сообщений; payload фактов — внутренний формат arm-core, не обмен между сервисами | изменение формата payload не поймает `make check` в этом репозитории; ловит тест arm-core | | 05.11.2026 | `legal_entity_name`/`group_name` добавлены и в `quality_failure_fact`, хотя design arm-core §4.3 их не перечислял | общее правило §4 design arm-core («имена ЮЛ и ГК копируются на момент факта») относится ко всем фактам; итемized список там был неполным | лишние 2 столбца, если экран всё же джойнит live-справочник для отказов | +| 07.11.2026 | Схема перенесена в `contracts/metrics/quality-facts.schema.json` (R-16 arm-core) | в корне `contracts/` каждая `*.schema.json` обязана иметь копию в сервисах (`contract_identity.py`); подкаталог глубины 2 вне `examples/` копию не требует — схема не относится к NATS-контракту распознавания; содержание схемы не менялось | при возврате в корень тесты идентичности tabular-parser и scan-gateway покраснеют | diff --git a/openspec/changes/quality-metrics/proposal.md b/openspec/changes/quality-metrics/proposal.md index 8797cad..50b75e3 100644 --- a/openspec/changes/quality-metrics/proposal.md +++ b/openspec/changes/quality-metrics/proposal.md @@ -31,7 +31,7 @@ API, экран. `tabular-parser` и `scan-gateway` не меняются. - **`stored_file.is_scan`** — признак скан/цифровой PDF, определяется при загрузке по текстовому слою. - **`permission_object`**: новое значение `QUALITY_METRICS` — объект права для экрана (действие `VIEW`, право `QUALITY_METRICS_VIEW`; seed — в arm-core). -- **`docs/contracts/quality-facts.schema.json`** — JSON Schema payload (jsonb) трёх фактов. +- **`docs/contracts/metrics/quality-facts.schema.json`** — JSON Schema payload (jsonb) трёх фактов. - **`docs/context/05-domain-rules.md` §14** — счёт документов/матрица причин, правило атрибуции правки (сервис/наш разбор), правило «документ клиента» (акцепт жёстких нарушений), признак скана. diff --git a/openspec/changes/quality-metrics/specs/quality-metrics-model/spec.md b/openspec/changes/quality-metrics/specs/quality-metrics-model/spec.md index 9d23a8a..6c458cd 100644 --- a/openspec/changes/quality-metrics/specs/quality-metrics-model/spec.md +++ b/openspec/changes/quality-metrics/specs/quality-metrics-model/spec.md @@ -55,7 +55,7 @@ того же файла ### Requirement: Контракт payload не входит в `make check` этого репозитория -`contracts/quality-facts.schema.json` SHALL существовать как валидная JSON Schema (Draft 2020-12), но SHALL NOT +`contracts/metrics/quality-facts.schema.json` SHALL существовать как валидная JSON Schema (Draft 2020-12), но SHALL NOT быть подключена к `scripts/validate_contracts.py` — payload не является сообщением NATS-контракта распознавания. #### Scenario: `make check` в arm-ka-docs