Автоподтверждение чистых документов (#64, OQ-157) #69

Merged
aep merged 10 commits from feat/64-auto-confirm into main 2026-10-08 17:08:36 +03:00
Owner

Closes #64

Сливать вместе с RSHB/arm-ka-docs#71 (правило §9.3/§9.5, OQ-157, гайды).

Что сделано

Чистый документ (маппинг сделал бы его RECOGNIZED) сразу становится CONFIRMED от имени системы: confirmed_by = NULL, audit_event(DOCUMENT_CONFIRM) с user_id = NULL и описанием «автоподтверждение: без замечаний»; привязывается к версиям и двигает их как при ручном подтверждении (переход от stored_file.uploaded_by, комментарий «автоподтверждение документа <тип> [<счёт>]»). Файл с автоподтверждёнными документами можно удалить, пока все версии с их привязками в INITIATED/DOCUMENTS_PROCESSING/DATA_CORRECTION. DBML и миграции не менялись. Спека: openspec/changes/auto-confirm-clean-documents/ (openspec validate --strict — валиден).

Задача Коммит Суть
1 ff65f21 on_document_confirmed(changed_by, comment); при changed_by=None привязка есть, перехода нет
2 588c098 form_confirmable / statement_hard_failures — одни условия формы для ручного и автоматического пути
3 b48d9e6 services/auto_confirm.py
4 3830e71 вызов в result_mapping._map_candidate: map_file → автозамена → auto_confirm → on_documents_mapped
5 256ddcb удаление файла: bound_versions / unbind_documents, FILE_DELETE.after_value.unbound_version_ids
6 e7bef70 CLAUDE.md, README, design.md
финал. ревью 8122205, 5f41550 правки по финальному ревью (opus)
Task 7 (правила и гайды) — в PR arm-ka-docs.

make check-full

Прогон на ветке (хвост вывода):

ruff check: All checks passed!   ruff format --check: ok   mypy src scripts: Success: no issues found in 143 source files
test (без БД):          1261 passed, 848 deselected in 26.06s
dbml-check, check-infra: без ошибок
test-integration:        847 passed, 1262 deselected in 333.25s
e2e:                     см. O-3 — 1-й прогон failed (60 с без результата), повторный прогон: 1 passed in 4.28s
docker-build, web-check: EXIT=0 (rsbuild, tsc, biome)

Отдельно (до финальных правок документации): pytest tests -m "not e2e" — 2108 passed.

Находки (маркер / суть / статус)

Маркер Суть Статус
T1.1 при changed_by=None лог пишется на каждую версию (шумно) deferred
T1.2 тест None только для INITIATED rejected: DOCUMENTS_PROCESSING идёт тем же кодом (MOVES_TO_CORRECTION)
T2.1 нет § в docstring form_confirmable fixed 8122205
T2.2 акцепт в тесте через created_at rejected: условие смотрит только is not None
T3.1 import json внутри тестов deferred
T3.2 дубль чтения ИНН golden в двух тестах deferred
T3.3 повторный get_meta после form_confirmable rejected: лишний запрос, не ��ефект
T4.1 _history_of внутри открытой сессии deferred
T4.2 = M-1 mixed-тест не фиксировал порядок D-1 (кто сделал переход) fixed 8122205 (проверено перестановкой: тест падает)
T4.3 = M-7 локальный импорт auto_confirm из-за цикла documents → result_mapping → auto_confirm → statements → documents deferred (техдолг: вынести form_confirmable/FORM_TYPES)
T5.1 после 409 не сверяются оставшиеся привязки/статусы deferred
T5.2 zip(strict=False) в фабрике теста deferred
T6.1 README: вставка про unbound_version_ids ломала фразу fixed 8122205
T6.2 README: нет 409 ALREADY_CONFIRMED в таблице эндпоинтов fixed 8122205
T6.3 README: примечание про RECOGNIZED пунктом списка fixed 8122205
T6.4 CLAUDE.md: цепочка без «автозамена» fixed 8122205
T6.5 design D-4: «по всем статусам» ≠ код (IN_WORK_STATUSES) fixed 8122205
I-1 README: DISCLOSURE/OTHER, e2e, схема пути, «RECOGNIZED с замечаниями», порядок блокировок удаления fixed 8122205
M-2 текст 409 «на согласовании» неточен (CANCELLED/REJECTED/ARCHIVED тоже блокируют) fixed 8122205 (код не менялся)
M-3 гонка в bound_versions при будущем «вернуть на доработку» (Срез 7) deferred
M-4 нет проверки лог-строки при uploaded_by NULL fixed 8122205
M-5 docstring/хрупкий assert в test_exchange_and_mapping_write_no_audit_events fixed 8122205
M-6 proposal Impact (documents-api, repositories/files.py); нет tasks.md Impact — fixed 8122205; tasks.md не добавлялся (в change его нет, validate --strict проходит) — deferred до openspec archive
F-1 README «Ограничения Среза 2c»: «файл удалить нельзя» устарело после OQ-157 fixed 5f41550
T7.1–T7.10 находки ревью Task 7 (arm-ka-docs): формы F1–F17 в qa-guide, §9.2, §9.5 п.5, DISCLOSURE/OTHER, W17 и minor fixed (docs e975f56, 6141828)
T7.11 / T7.12 qa-guide W17: ссылка на «раздел 8.7»; $H/$LE_QA в разделе 8 не определены deferred
O-1 коммиты исполнителей-haiku получили трейлер Haiku 5.5 вместо Opus 5.5 fixed: сообщения переписаны (деревья идентичны)
O-2 UI-проверка «✓ Подтвердить» для NEEDS_CHECK больше не покрыта W17 (остаются W22/W27) deferred (сценарий QA)
O-3 e2e test_real_osv_is_parsed_end_to_end нестабилен из-за стенда владельца: задание ack'нуто tabular-parser, результат в queue group arm-core иногда забирает ядро стенда. Первый прогон ветки — failed (60 с), повтор — passed (4.3 с); на чистом main (d8bf5b2, отдельный detached worktree): 1-й прогон passed (5.6 с), 2-й failed (62 с). Известная история (RSHB/arm-scan-gateway#19). Стенд не трогал deferred

Rulings I made

№ Решение design.md Цена ошибки
R-1 В тесте form_confirmable ломается строка 2200, а не 2400 из плана (соотношения с 2400 нежёсткие) №8 только тест
R-2 В тестах uploaded_by — реальный пользователь (FK app_user), не uuid4() №9 нет
R-3 В тестах «ручног�� подтверждения» удаления проставлен confirmed_by (иначе по новому правилу D-4 это автоподтверждение) №10 нет
R-4 make check-full — один раз в конце, не внутри Task 6 №12 правка после ревью, если что-то найдётся
R-5 M-3 и вынос form_confirmable из цикла импортов — техдолг №13 при добавлении «вернуть на доработку» (Срез 7) нужен 409 для версий вне множества, заблокированного lock_versions_for_entity
R-6 CANCELLED/REJECTED/ARCHIVED версия с привязкой блокирует удаление (буквально по спеке; привязки при отмене версии не снимаются) №14 файл из отменённой версии не удалить — вопрос владельцу
R-7 Локальный импорт auto_confirm в _map_candidate принят №11 техдолг T4.3/M-7
Task 7: реализатор отклонился от брифа, правя qa-guide U2/U3/U8/U9 и добавив U17/U18 — принято как необходимое для непротиворечивости.

Deferred (для follow-up issue при закрытии)

T1.1, T3.1, T3.2, T4.1, T4.3/M-7, T5.1, T5.2, M-3, M-6 (tasks.md при архивации), T7.11, T7.12, O-2, O-3.

🤖 Generated with Claude Code

Closes #64 Сливать вместе с RSHB/arm-ka-docs#71 (правило §9.3/§9.5, OQ-157, гайды). ## Что сделано Чистый документ (маппинг сделал бы его `RECOGNIZED`) сразу становится `CONFIRMED` от имени системы: `confirmed_by = NULL`, `audit_event(DOCUMENT_CONFIRM)` с `user_id = NULL` и описанием «автоподтверждение: без замечаний»; привязывается к версиям и двигает их как при ручном подтверждении (переход от `stored_file.uploaded_by`, комментарий «автоподтверждение документа <тип> [<счёт>]»). Файл с автоподтверждёнными документами можно удалить, пока все версии с их привязками в `INITIATED`/`DOCUMENTS_PROCESSING`/`DATA_CORRECTION`. DBML и миграции не менялись. Спека: `openspec/changes/auto-confirm-clean-documents/` (`openspec validate --strict` — валиден). | Задача | Коммит | Суть | |---|---|---| | 1 | ff65f21 | `on_document_confirmed(changed_by, comment)`; при `changed_by=None` привязка есть, перехода нет | | 2 | 588c098 | `form_confirmable` / `statement_hard_failures` — одни условия формы для ручного и автоматического пути | | 3 | b48d9e6 | `services/auto_confirm.py` | | 4 | 3830e71 | вызов в `result_mapping._map_candidate`: `map_file` → автозамена → `auto_confirm` → `on_documents_mapped` | | 5 | 256ddcb | удаление файла: `bound_versions` / `unbind_documents`, `FILE_DELETE.after_value.unbound_version_ids` | | 6 | e7bef70 | CLAUDE.md, README, design.md | | финал. ревью | 8122205, 5f41550 | правки по финальному ревью (opus) | Task 7 (правила и гайды) — в PR arm-ka-docs. ## make check-full Прогон на ветке (хвост вывода): ``` ruff check: All checks passed! ruff format --check: ok mypy src scripts: Success: no issues found in 143 source files test (без БД): 1261 passed, 848 deselected in 26.06s dbml-check, check-infra: без ошибок test-integration: 847 passed, 1262 deselected in 333.25s e2e: см. O-3 — 1-й прогон failed (60 с без результата), повторный прогон: 1 passed in 4.28s docker-build, web-check: EXIT=0 (rsbuild, tsc, biome) ``` Отдельно (до финальных правок документации): `pytest tests -m "not e2e"` — 2108 passed. ## Находки (маркер / суть / статус) | Маркер | Суть | Статус | |---|---|---| | T1.1 | при `changed_by=None` лог пишется на каждую версию (шумно) | deferred | | T1.2 | тест `None` только для `INITIATED` | rejected: `DOCUMENTS_PROCESSING` идёт тем же кодом (`MOVES_TO_CORRECTION`) | | T2.1 | нет § в docstring `form_confirmable` | fixed 8122205 | | T2.2 | акцепт в тесте через `created_at` | rejected: условие смотрит только `is not None` | | T3.1 | `import json` внутри тестов | deferred | | T3.2 | дубль чтения ИНН golden в двух тестах | deferred | | T3.3 | повторный `get_meta` после `form_confirmable` | rejected: лишний запрос, не ��ефект | | T4.1 | `_history_of` внутри открытой сессии | deferred | | T4.2 = M-1 | mixed-тест не фиксировал порядок D-1 (кто сделал переход) | fixed 8122205 (проверено перестановкой: тест падает) | | T4.3 = M-7 | локальный импорт `auto_confirm` из-за цикла `documents → result_mapping → auto_confirm → statements → documents` | deferred (техдолг: вынести `form_confirmable`/`FORM_TYPES`) | | T5.1 | после 409 не сверяются оставшиеся привязки/статусы | deferred | | T5.2 | `zip(strict=False)` в фабрике теста | deferred | | T6.1 | README: вставка про `unbound_version_ids` ломала фразу | fixed 8122205 | | T6.2 | README: нет 409 `ALREADY_CONFIRMED` в таблице эндпоинтов | fixed 8122205 | | T6.3 | README: примечание про RECOGNIZED пунктом списка | fixed 8122205 | | T6.4 | CLAUDE.md: цепочка без «автозамена» | fixed 8122205 | | T6.5 | design D-4: «по всем статусам» ≠ код (`IN_WORK_STATUSES`) | fixed 8122205 | | I-1 | README: DISCLOSURE/OTHER, e2e, схема пути, «RECOGNIZED с замечаниями», порядок блокировок удаления | fixed 8122205 | | M-2 | текст 409 «на согласовании» неточен (CANCELLED/REJECTED/ARCHIVED тоже блокируют) | fixed 8122205 (код не менялся) | | M-3 | гонка в `bound_versions` при будущем «вернуть на доработку» (Срез 7) | deferred | | M-4 | нет проверки лог-строки при `uploaded_by` NULL | fixed 8122205 | | M-5 | docstring/хрупкий assert в `test_exchange_and_mapping_write_no_audit_events` | fixed 8122205 | | M-6 | proposal Impact (`documents-api`, `repositories/files.py`); нет `tasks.md` | Impact — fixed 8122205; `tasks.md` не добавлялся (в change его нет, `validate --strict` проходит) — deferred до `openspec archive` | | F-1 | README «Ограничения Среза 2c»: «файл удалить нельзя» устарело после OQ-157 | fixed 5f41550 | | T7.1–T7.10 | находки ревью Task 7 (arm-ka-docs): формы F1–F17 в qa-guide, §9.2, §9.5 п.5, DISCLOSURE/OTHER, W17 и minor | fixed (docs e975f56, 6141828) | | T7.11 / T7.12 | qa-guide W17: ссылка на «раздел 8.7»; `$H`/`$LE_QA` в разделе 8 не определены | deferred | | O-1 | коммиты исполнителей-haiku получили трейлер `Haiku 5.5` вместо `Opus 5.5` | fixed: сообщения переписаны (деревья идентичны) | | O-2 | UI-проверка «✓ Подтвердить» для `NEEDS_CHECK` больше не покрыта W17 (остаются W22/W27) | deferred (сценарий QA) | | O-3 | e2e `test_real_osv_is_parsed_end_to_end` нестабилен из-за стенда владельца: задание ack'нуто tabular-parser, результат в queue group `arm-core` иногда забирает ядро стенда. Первый прогон ветки — failed (60 с), повтор — passed (4.3 с); на чистом `main` (d8bf5b2, отдельный detached worktree): 1-й прогон passed (5.6 с), 2-й failed (62 с). Известная история (RSHB/arm-scan-gateway#19). Стенд не трогал | deferred | ## Rulings I made | № | Решение | design.md | Цена ошибки | |---|---|---|---| | R-1 | В тесте `form_confirmable` ломается строка 2200, а не 2400 из плана (соотношения с 2400 нежёсткие) | №8 | только тест | | R-2 | В тестах `uploaded_by` — реальный пользователь (FK `app_user`), не `uuid4()` | №9 | нет | | R-3 | В тестах «ручног�� подтверждения» удаления проставлен `confirmed_by` (иначе по новому правилу D-4 это автоподтверждение) | №10 | нет | | R-4 | `make check-full` — один раз в конце, не внутри Task 6 | №12 | правка после ревью, если что-то найдётся | | R-5 | M-3 и вынос `form_confirmable` из цикла импортов — техдолг | №13 | при добавлении «вернуть на доработку» (Срез 7) нужен 409 для версий вне множества, заблокированного `lock_versions_for_entity` | | R-6 | CANCELLED/REJECTED/ARCHIVED версия с привязкой блокирует удаление (буквально по спеке; привязки при отмене версии не снимаются) | №14 | файл из отменённой версии не удалить — **вопрос владельцу** | | R-7 | Локальный импорт `auto_confirm` в `_map_candidate` принят | №11 | техдолг T4.3/M-7 | Task 7: реализатор отклонился от брифа, правя qa-guide U2/U3/U8/U9 и добавив U17/U18 — принято как необходимое для непротиворечивости. ## Deferred (для follow-up issue при закрытии) T1.1, T3.1, T3.2, T4.1, T4.3/M-7, T5.1, T5.2, M-3, M-6 (`tasks.md` при архивации), T7.11, T7.12, O-2, O-3. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 10 commits 2026-10-08 17:03:39 +03:00
Proposal, design (D-1…D-6, решения без обсуждения №1–7) и дельты osv-result-mapping,
primary-files, audit-trail: чистый документ при маппинге сразу CONFIRMED (система,
confirmed_by NULL; переход версии — от загрузившего), удаление автоподтверждённых
файлов до DATA_CORRECTION включительно. Решение владельца 08.10.2026, ТЗ 03_9 п. 4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 задач: хук подтверждения с автором перехода, form_confirmable, auto_confirm,
вызов в маппинге, удаление файла, документация arm-core, правило и OQ-157 в docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Условия подтверждения формы ББ/ОФР вынесены в statement_hard_failures и form_confirmable
(модульные функции services/statements.py); ручной путь (documents._check_statement) использует
тот же statement_hard_failures и отвечает 409. Тест с нарушением строгого соотношения на 2200
(соотношения с 2400 в словаре мягкие).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep merged commit 020edd0fdd into main 2026-10-08 17:08:36 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/arm-core#69
No description provided.