# Feature Specification: Clean Release Compliance Subsystem Redesign **Feature Branch**: `025-clean-release-compliance` **Created**: 2026-03-09 **Status**: Draft **Input**: User description: "Редизайн текущего clean release TUI-checker в нормальную API/CLI-first release/compliance subsystem с разделением domain/application/infrastructure/interfaces, immutable snapshots, append-only compliance evidence, approval/publication flow, thin TUI client, REST API и интеграцией с TaskManager." ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Headless candidate and manifest lifecycle (Priority: P1) Как release-менеджер или CI pipeline, я хочу регистрировать релиз-кандидат, импортировать артефакты и строить manifest без TUI, чтобы вход в release workflow был воспроизводимым в автоматизированном или headless сценарии. **Why this priority**: Это базовая ценность редизайна. Пока жизненный цикл кандидата зависит от TUI, release flow не годится для автоматизации и надёжного enterprise use. **Independent Test**: Можно создать кандидата, импортировать набор артефактов, построить manifest и запросить overview только через CLI или HTTP API, не используя интерактивный интерфейс. **Acceptance Scenarios**: 1. **Given** у оператора есть описание релиз-кандидата и набор артефактов, **When** он выполняет headless workflow регистрации, импорта и построения manifest, **Then** система сохраняет кандидата и immutable snapshot manifest без участия TUI. 2. **Given** manifest успешно построен, **When** оператор запрашивает candidate overview через CLI или API, **Then** он получает актуальный lifecycle state и идентификатор latest manifest. 3. **Given** pipeline подготавливает следующий этап release workflow, **When** он использует headless candidate and manifest operations, **Then** ему не требуется интерактивный интерфейс для продолжения release process. --- ### User Story 2 - Trusted and immutable compliance evidence (Priority: P1) Как сотрудник комплаенса или аудита, я хочу, чтобы policy, registry, manifest, run, violations и report были отделены друг от друга и сохранялись как доверенные или append-only сущности, чтобы итог выпуска был доказуемым и не зависел от UI-состояния или случайных env/json подмен. **Why this priority**: Главная архитектурная проблема текущего решения - смешение trust boundaries и UI logic с бизнес-решениями. Без исправления этого нельзя считать результат compliance надёжным. **Independent Test**: Можно зафиксировать policy snapshot и registry snapshot, выполнить run, затем проверить, что manifest/report/violations не переписывались и что итоговый статус выводится только из сохранённого evidence. **Acceptance Scenarios**: 1. **Given** активная policy получена из доверенного policy store, **When** запускается compliance, **Then** run использует snapshot policy и snapshot registry, а не значения из UI или временных env-переменных. 2. **Given** для кандидата уже создан manifest, **When** входные данные кандидата меняются, **Then** система создаёт новый version manifest вместо изменения существующего snapshot. 3. **Given** run завершён, **When** оператор запрашивает историю проверки, **Then** старые run, violations и reports остаются доступными и не удаляются в real mode. --- ### User Story 3 - Controlled approval and publication gate (Priority: P2) Как владелец релиза, я хочу выполнять approve, publish и revoke только после валидного compliance результата, чтобы состояние выпуска было формально управляемым и не зависело от ручных договорённостей. **Why this priority**: Проверка compliance имеет смысл только тогда, когда она реально управляет дальнейшими переходами release lifecycle. **Independent Test**: Можно попытаться утвердить или опубликовать кандидата в запрещённом состоянии и убедиться, что система блокирует переход; затем пройти валидный путь `CHECK_PASSED -> APPROVED -> PUBLISHED`. **Acceptance Scenarios**: 1. **Given** кандидат имеет последний report со статусом `PASSED`, **When** уполномоченный оператор выполняет approve, **Then** система фиксирует approval decision и переводит кандидата в состояние `APPROVED`. 2. **Given** кандидат не имеет успешного compliance report или latest approval decision имеет значение `REJECTED`, **When** оператор пытается выполнить approve или publish вне допустимого правила, **Then** система отклоняет действие и сообщает причину блокировки. 3. **Given** кандидат опубликован в целевой канал, **When** требуется отзыв выпуска, **Then** система создаёт publication revocation record без удаления исходной истории публикации. --- ### User Story 4 - Thin operational interfaces (Priority: P3) Как инженер сопровождения, я хочу использовать TUI и другие интерфейсы только как клиенты чтения и запуска операций, чтобы интерфейсы не содержали скрытой бизнес-логики, не подменяли policy и не создавали визуальные fake-runs. **Why this priority**: Тонкие интерфейсы упрощают сопровождение, делают поведение одинаковым между CLI, API, TUI и будущим Web UI, а также уменьшают риск расхождения логики. **Independent Test**: Можно открыть TUI, выполнить build manifest, run compliance, approve и publish, а затем проверить, что все операции и их последствия совпадают с CLI/API сценариями и не зависят от внутреннего UI state. **Acceptance Scenarios**: 1. **Given** оператор открывает TUI, **When** он запускает build manifest или compliance, **Then** TUI вызывает application services и только отображает актуальные DTO/статусы. 2. **Given** система работает в demo mode, **When** оператор запускает demo workflow, **Then** demo данные и demo history остаются полностью изолированными от real mode. 3. **Given** оператор работает в headless окружении без TTY, **When** он пытается использовать функциональность release lifecycle, **Then** система направляет его в CLI/API путь, а не переводит TUI в скрытый псевдо-headless режим. ### Edge Cases - Что происходит, если артефакт имеет расхождение между `declared_category` и `detected_category`? - Что происходит, если кандидат изменился после построения manifest, но до запуска compliance? - Как система различает business blocked, invalid input и system error при возврате статуса и exit code? - Что происходит, если policy store недоступен в момент запроса compliance? - Как обрабатывается повторный approve или повторный publish для уже терминально обработанного кандидата? - Что происходит, если run был отменён или task crashed после старта, но до генерации report? - Как система предотвращает пересечение demo namespace и real namespace в storage и audit history? ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: Система MUST предоставлять программно управляемый release lifecycle, доступный без TUI через CLI и HTTP API. - **FR-002**: Система MUST поддерживать отдельную сущность release candidate с идентификатором, версией, ссылкой на source snapshot, provenance и статусом lifecycle. - **FR-003**: Система MUST поддерживать импорт и хранение candidate artifacts с checksum, размером, declared category и detected category. - **FR-004**: Система MUST различать declared category и detected category и фиксировать факт их расхождения как часть compliance evidence. - **FR-005**: Система MUST строить distribution manifest как отдельный immutable snapshot с собственным идентификатором, version, digest и полным содержимым. - **FR-006**: Если состав кандидата изменился после построения manifest, система MUST создавать новый manifest version вместо изменения существующего snapshot. - **FR-007**: Система MUST получать policy только из доверенного policy store и сохранять используемую policy как immutable policy snapshot. - **FR-008**: Система MUST получать source registry только из доверенного registry source и сохранять используемый registry как immutable snapshot. - **FR-009**: Ни один интерфейс, пользовательский ввод или env-переменная MUST NOT определять содержимое policy snapshot, registry snapshot, итоговый report status или audit history. - **FR-010**: Система MUST создавать отдельную сущность compliance run, связанную с candidate, manifest, policy snapshot и registry snapshot. - **FR-011**: Compliance run MUST сохранять append-only stage execution records, violations и итоговый report. - **FR-012**: Система MUST поддерживать статусы выполнения run не менее чем `PENDING`, `RUNNING`, `SUCCEEDED`, `FAILED`, `CANCELLED`. - **FR-013**: Система MUST поддерживать итоговые статусы compliance не менее чем `PASSED`, `BLOCKED`, `ERROR`. - **FR-014**: Система MUST различать outcome types `PASSED`, `BLOCKED`, `ERROR_INVALID_INPUT`, `ERROR_SYSTEM` и делать их однозначно наблюдаемыми через CLI/API. - **FR-015**: Compliance pipeline MUST состоять из независимых стадий с отдельным stage result, decision, details и violations. - **FR-016**: Система MUST позволять расширять compliance pipeline новыми стадиями без переписывания интерфейсов запуска и чтения run. - **FR-017**: Release candidate lifecycle MUST поддерживать разрешённые переходы `DRAFT -> PREPARED -> MANIFEST_BUILT -> CHECK_PENDING -> CHECK_RUNNING -> CHECK_PASSED|CHECK_BLOCKED|CHECK_ERROR -> APPROVED -> PUBLISHED -> REVOKED`. - **FR-018**: Система MUST блокировать `APPROVED` без успешного compliance result и MUST блокировать `PUBLISHED` без approval. - **FR-019**: Система MUST сохранять отдельный approval decision с actor, временем, комментарием и ссылкой на report. - **FR-020**: Система MUST трактовать approval и reject как immutable decisions, где latest decision governs publication gate; `REJECTED` блокирует публикацию, но не меняет compliance evidence и не переписывает lifecycle state кандидата. - **FR-021**: Система MUST сохранять отдельный publication record с channel, actor, временем, ref и статусом, а revoke MUST оформляться как отдельное действие без удаления исходной публикации. - **FR-022**: Каждое long-running compliance execution MUST выполняться как асинхронная task execution единица с наблюдаемым lifecycle, логами stage events и итоговой summary. - **FR-023**: API запуск compliance MUST быть non-blocking и возвращать идентификаторы run и связанной task execution для последующего наблюдения. - **FR-024**: Система MUST вести append-only audit log для создания кандидата, импорта артефактов, построения manifest, запуска compliance, завершения стадий, фиксации violations, генерации report, approval, publication и revoke. - **FR-025**: В real mode система MUST NOT удалять historical runs, reports, violations или audit events. - **FR-026**: Demo mode MUST использовать отдельный storage namespace, отдельные policy snapshots и отдельную историю, полностью изолированную от real mode. - **FR-027**: TUI MUST быть thin client интерфейсом чтения и запуска операций и MUST NOT скрыто строить manifest, подмешивать policy, подменять registry, очищать history реального режима или создавать fake run только ради UI. - **FR-028**: Для headless сценариев система MUST предоставлять CLI команды для candidate lifecycle, compliance, approval, publication и revoke. - **FR-029**: Система MUST предоставлять HTTP endpoints для candidate lifecycle, manifest operations, compliance runs, report retrieval, approval и publication. - **FR-030**: Система MUST предоставлять сводное представление candidate overview с данными о последнем manifest, последнем run, последнем report, latest policy snapshot, latest approval/publication state и текущем lifecycle state. - **FR-031**: Compliance report MUST быть отдельной immutable сущностью с финальным статусом, summary и связью с конкретным run. - **FR-032**: Система MUST позволять оператору получать список violations и stage details отдельно от итогового report. - **FR-033**: Business actions для candidate, manifest, compliance, approval и publication MUST использовать единый application facade, одинаковый для CLI, TUI, API и будущего Web UI. ### Key Entities *(include if feature involves data)* - **Release Candidate**: Объект управления выпуском, описывающий, что именно собираются выпустить и в каком lifecycle состоянии это находится. - **Candidate Artifact**: Артефакт релиз-кандидата с доказуемыми признаками происхождения, контрольной суммой и двумя категориями классификации. - **Distribution Manifest**: Immutable snapshot состава поставки, зафиксированный для конкретного кандидата и конкретной версии manifest. - **Clean Policy Snapshot**: Доверенный immutable snapshot policy, использованный во время проверки. - **Source Registry Snapshot**: Доверенный immutable snapshot реестра разрешённых источников. - **Compliance Run**: Операционная сущность, представляющая отдельный запуск проверки для кандидата и manifest. - **Compliance Stage Run**: Результат выполнения отдельной стадии pipeline внутри конкретного run. - **Compliance Violation**: Зафиксированное нарушение с severity, evidence и ссылкой на stage/run. - **Compliance Report**: Отдельный immutable итоговый отчёт по завершённому run. - **Approval Decision**: Формальный акт approve/reject с actor, comment и ссылкой на report. - **Publication Record**: Формальная запись публикации или отзыва с channel и статусом. - **Candidate Overview**: Производное представление для интерфейсов, объединяющее состояние кандидата, latest manifest, latest run и latest report. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: 100% обязательных действий release lifecycle для стандартного сценария (`register -> import-artifacts -> build-manifest -> run-compliance -> approve -> publish`) выполняются без TUI через CLI или API. - **SC-002**: 100% завершённых compliance runs оставляют неизменяемый report и связанный audit trail, доступный для чтения после завершения. - **SC-003**: 100% попыток approve без успешного compliance result и publish без approval отклоняются системой. - **SC-004**: Не менее 95% стандартных запусков compliance получают machine-readable outcome без ручного исправления состояния системы. - **SC-005**: Не менее 90% операторов могут пройти базовый release workflow по quickstart без обращения к скрытым TUI-сценариям или ручным DB-операциям. - **SC-006**: Время получения идентификатора run/task после запроса запуска compliance не превышает 2 секунд для типового кандидата. - **SC-007**: В 100% real-mode сценариев historical runs, violations, reports и audit events не удаляются командами пользовательского интерфейса. ## Assumptions - В проекте уже доступен общий TaskManager, пригодный для оркестрации long-running compliance tasks. - Для policy и registry может быть предоставлен доверенный read-only источник, отдельный от пользовательского UI input. - Существующий clean-release модуль допускает поэтапную миграцию без одномоментного удаления старых API/TUI entrypoints. - Операторы релиза, approval actors и publication actors аутентифицированы существующими механизмами приложения. - Demo mode нужен для демонстрации и тестовых сценариев, но не должен влиять на real mode evidence.