Status: Accepted
Date: 2026-04-18
Протокол — юридический документ. Частично сгенерированный / "почти-полный" протокол не имеет смысла: в нём может не хватать выписки по принципиальному вопросу, или документ решения может быть битым. Такой протокол нельзя показывать бизнесу и нельзя подписывать — он вводит в заблуждение.
Референсный сервис в ряде мест шёл на компромиссы:
DocumentInsertProcessor) — при провале вставки в итоговый документ появлялся "красный текст" [ОШИБКА: ...] вместо пробрасывания исключения. → Протокол формировался с дырками.Extract сохранялся с externalStorageKey=null. → На следующем шаге загрузка падала рандомно.continue в цикле. → Протокол формировался без вопроса.Эти "компромиссы" — источник хаоса: баг в одном месте приводит к корректно выглядящему, но невалидному документу. Это нарушает бизнес-требование.
common-lib 3.4.0 закрыл часть этих проблем (C-1, ECM-C1, ECM-H1/H2) — теперь нижние слои пробрасывают исключения. В protocol 2.0 надо зафиксировать правило и следовать ему везде выше по стеку.
Pipeline генерации протокола строго fail-fast на любой ошибке:
IntegrationException, весь протокол падает.DocumentGenerationError, IntegrationException, NotFound внутри pipeline → pipe пробрасывает наверх.StructuredTaskScope в Phase 2 и Phase 3: конфигурация Joiner.anySuccessfulResultOrThrow → первая неудача отменяет остальные параллельные задачи.
Транзакционность:
DuplicateExtractException → fetch existing (race-condition-safe).Что не делаем:
try { ... } catch (Exception e) { log.error(...); continue; } в pipeline.null в обязательном поле после маппинга — ContractMismatch.Positive:
GlobalExceptionHandler вернёт структурированный ProblemDetail (RFC 9457).isTransient), permanent — не ретраим, возвращаем ошибку сразу.Negative:
DuplicateExtractException → cache-hit на следующей попытке + отдельный cleanup job (фаза 7, post-MVP).isTransient