Files
ss-tools/specs/025-clean-release-compliance/spec.md
2026-03-09 16:52:46 +03:00

154 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.