chore(specs): move clean-repo-enterprise spec from 020 to 023

This commit is contained in:
2026-03-03 19:50:53 +03:00
parent da24fb9253
commit 19898b1570
10 changed files with 1549 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
# Specification Quality Checklist: Clean Repository Enterprise Preparation
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-03-03
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## UX Consistency
- [x] Functional requirements fully support the 'Happy Path' in ux_reference.md
- [x] Error handling requirements match the 'Error Experience' in ux_reference.md
- [x] No requirements contradict the defined User Persona or Context
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Validation iteration: 1 (all checks passed).
- Дополнительно зафиксировано ограничение изолированного контура: для enterprise clean-профиля все ресурсы загружаются только с внутренних серверов компании, без внешнего интернета.
- UX зафиксирован как TUI-формат: интерактивный консольный сценарий на базе `ncurses` или совместимого аналога в [`ux_reference.md`](../ux_reference.md).

View File

@@ -0,0 +1,206 @@
openapi: 3.1.0
info:
title: Clean Release Compliance API
version: "1.0.0"
description: >
API contract for enterprise clean release validation in isolated corporate networks.
servers:
- url: https://internal-api.company.local
paths:
/api/clean-release/checks:
post:
summary: Start enterprise clean compliance check
operationId: startCleanComplianceCheck
tags: [clean-release]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/StartCheckRequest'
examples:
enterpriseClean:
value:
candidate_id: "2026.03.03-rc1"
profile: "enterprise-clean"
execution_mode: "tui"
responses:
"202":
description: Check run accepted
content:
application/json:
schema:
$ref: '#/components/schemas/StartCheckResponse'
"400":
description: Invalid request
"403":
description: Forbidden
"409":
description: Candidate is not eligible for check
/api/clean-release/checks/{check_run_id}:
get:
summary: Get compliance check status
operationId: getCleanComplianceStatus
tags: [clean-release]
parameters:
- name: check_run_id
in: path
required: true
schema:
type: string
responses:
"200":
description: Current check status
content:
application/json:
schema:
$ref: '#/components/schemas/CheckStatusResponse'
"404":
description: Check run not found
/api/clean-release/reports/{report_id}:
get:
summary: Get compliance report
operationId: getCleanComplianceReport
tags: [clean-release]
parameters:
- name: report_id
in: path
required: true
schema:
type: string
responses:
"200":
description: Compliance report
content:
application/json:
schema:
$ref: '#/components/schemas/ComplianceReportResponse'
"404":
description: Report not found
components:
schemas:
StartCheckRequest:
type: object
required: [candidate_id, profile, execution_mode]
properties:
candidate_id:
type: string
profile:
type: string
enum: [enterprise-clean, development]
execution_mode:
type: string
enum: [tui, ci]
StartCheckResponse:
type: object
required: [check_run_id, candidate_id, status, started_at]
properties:
check_run_id:
type: string
candidate_id:
type: string
status:
type: string
enum: [running]
started_at:
type: string
format: date-time
CheckStageResult:
type: object
required: [stage, status]
properties:
stage:
type: string
enum: [data_purity, internal_sources_only, no_external_endpoints, manifest_consistency]
status:
type: string
enum: [pass, fail, skipped]
details:
type: string
duration_ms:
type: integer
minimum: 0
Violation:
type: object
required: [violation_id, category, severity, location, remediation, blocked_release]
properties:
violation_id:
type: string
category:
type: string
enum: [data-purity, external-source, manifest-integrity, policy-conflict, operational-risk]
severity:
type: string
enum: [critical, high, medium, low]
location:
type: string
evidence:
type: string
remediation:
type: string
blocked_release:
type: boolean
detected_at:
type: string
format: date-time
CheckStatusResponse:
type: object
required: [check_run_id, candidate_id, final_status, checks]
properties:
check_run_id:
type: string
candidate_id:
type: string
final_status:
type: string
enum: [running, compliant, blocked, failed]
started_at:
type: string
format: date-time
finished_at:
type: string
format: date-time
checks:
type: array
items:
$ref: '#/components/schemas/CheckStageResult'
violations:
type: array
items:
$ref: '#/components/schemas/Violation'
ComplianceReportResponse:
type: object
required:
[report_id, check_run_id, candidate_id, generated_at, final_status, operator_summary, violations_count, blocking_violations_count]
properties:
report_id:
type: string
check_run_id:
type: string
candidate_id:
type: string
generated_at:
type: string
format: date-time
final_status:
type: string
enum: [compliant, blocked, failed]
operator_summary:
type: string
structured_payload_ref:
type: string
violations_count:
type: integer
minimum: 0
blocking_violations_count:
type: integer
minimum: 0
violations:
type: array
items:
$ref: '#/components/schemas/Violation'

View File

@@ -0,0 +1,190 @@
# Module Contracts: Clean Repository Enterprise Preparation
## Contract Scope
Этот документ фиксирует семантические контракты новых модулей для enterprise clean-подготовки.
Контракты синхронизированы с UX состояниями из [`ux_reference.md`](../ux_reference.md) и моделью данных из [`data-model.md`](../data-model.md).
---
# [DEF:backend.src.services.clean_release.policy_engine:Module]
# @TIER: CRITICAL
# @SEMANTICS: clean-release, policy, classification, compliance, enterprise
# @PURPOSE: Evaluate artifact and source policies for enterprise clean profile with deterministic outcomes.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> backend.src.models.clean_release.CleanProfilePolicy
# @RELATION: DEPENDS_ON -> backend.src.models.clean_release.ResourceSourceRegistry
# @INVARIANT: For enterprise-clean profile, external resource sources are always forbidden.
# @TEST_CONTRACT: CleanPolicyEvaluation -> PolicyDecision
# @TEST_FIXTURE: policy_enterprise_clean -> {"external_source_forbidden": true, "prohibited_artifact_categories": ["test-data","demo-data"]}
# @TEST_EDGE: conflicting_rules -> same artifact matches allowed and prohibited patterns, must resolve to prohibited
# @TEST_EDGE: missing_registry -> enterprise-clean policy without internal_source_registry_ref must fail validation
# @TEST_EDGE: empty_prohibited_categories -> must fail policy activation for enterprise-clean
# @TEST_INVARIANT: deterministic_policy_result -> VERIFIED_BY: [policy_enterprise_clean, conflicting_rules]
class CleanPolicyEngine:
# @PURPOSE: Initialize policy engine with active policy and internal source registry.
# @PRE: Active policy exists and is internally consistent.
# @POST: Engine is ready for deterministic classification.
def __init__(self): ...
# @PURPOSE: Validate policy consistency before any release operation.
# @PRE: Policy payload is provided.
# @POST: Returns validation result with blocking reasons if inconsistent.
def validate_policy(self): ...
# @PURPOSE: Classify one artifact against policy categories.
# @PRE: Artifact metadata is provided.
# @POST: Returns one of [required-system, allowed, excluded-prohibited].
def classify_artifact(self): ...
# @PURPOSE: Validate that resource source belongs to internal registry.
# @PRE: Source endpoint is provided.
# @POST: Returns pass/fail and violation payload for non-internal sources.
def validate_resource_source(self): ...
# @PURPOSE: Evaluate full candidate policy compliance input.
# @PRE: Candidate artifacts and sources are provided.
# @POST: Returns deterministic policy decision and violations list.
def evaluate_candidate(self): ...
# [/DEF:backend.src.services.clean_release.policy_engine:Module]
---
# [DEF:backend.src.services.clean_release.compliance_orchestrator:Module]
# @TIER: CRITICAL
# @SEMANTICS: clean-release, compliance, orchestrator, release-gate, audit
# @PURPOSE: Orchestrate multi-stage compliance checks and produce final COMPLIANT/BLOCKED decision.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.policy_engine
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.report_builder
# @RELATION: DEPENDS_ON -> backend.src.models.clean_release.ComplianceCheckRun
# @INVARIANT: A check run cannot end with COMPLIANT if any mandatory stage fails.
# @TEST_CONTRACT: ComplianceRunInput -> ComplianceRunResult
# @TEST_FIXTURE: compliant_candidate -> {"stages":{"data_purity":"pass","internal_sources_only":"pass","no_external_endpoints":"pass","manifest_consistency":"pass"}}
# @TEST_EDGE: stage_failure_blocks_release -> one mandatory stage fail must force BLOCKED
# @TEST_EDGE: missing_stage_result -> incomplete stage set must fail run as invalid
# @TEST_EDGE: report_generation_error -> run must be marked failed, never falsely compliant
# @TEST_INVARIANT: blocking_gate_integrity -> VERIFIED_BY: [compliant_candidate, stage_failure_blocks_release]
class CleanComplianceOrchestrator:
# @PURPOSE: Start new compliance check run for a release candidate.
# @PRE: Candidate exists and policy is active.
# @POST: Check run created with status RUNNING.
def start_check_run(self): ...
# @PURPOSE: Execute mandatory stage sequence deterministically.
# @PRE: Check run is in RUNNING state.
# @POST: Stage statuses recorded for all mandatory checks.
def execute_stages(self): ...
# @PURPOSE: Finalize run status and trigger report build.
# @PRE: Stage execution completed or failed.
# @POST: Final status set to COMPLIANT/BLOCKED/FAILED with immutable result summary.
def finalize_run(self): ...
# [/DEF:backend.src.services.clean_release.compliance_orchestrator:Module]
---
# [DEF:backend.src.services.clean_release.report_builder:Module]
# @TIER: CRITICAL
# @SEMANTICS: compliance-report, audit, release, violations, summary
# @PURPOSE: Build operator-readable and machine-readable compliance reports for release audit.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> backend.src.models.clean_release.ComplianceReport
# @RELATION: DEPENDS_ON -> backend.src.models.clean_release.ComplianceViolation
# @INVARIANT: Report counters must match underlying violations set.
# @TEST_CONTRACT: ComplianceRunResult -> ComplianceReport
# @TEST_FIXTURE: blocked_with_two_violations -> {"violations":[{"category":"data-purity","blocked_release":true},{"category":"external-source","blocked_release":true}]}
# @TEST_EDGE: empty_violations_for_blocked -> blocked run without violations must fail report validation
# @TEST_EDGE: counter_mismatch -> blocking_violations_count cannot exceed violations_count
# @TEST_EDGE: missing_operator_summary -> report invalid without human-readable summary
# @TEST_INVARIANT: report_counter_consistency -> VERIFIED_BY: [blocked_with_two_violations, counter_mismatch]
class ComplianceReportBuilder:
# @PURPOSE: Build normalized report payload from run result.
# @PRE: Run has terminal status.
# @POST: Report payload includes required machine and operator fields.
def build_report_payload(self): ...
# @PURPOSE: Persist report and return report reference.
# @PRE: Report payload validated.
# @POST: Report saved with stable report_id.
def persist_report(self): ...
# [/DEF:backend.src.services.clean_release.report_builder:Module]
---
# [DEF:backend.src.scripts.clean_release_tui:Module]
# @TIER: CRITICAL
# @SEMANTICS: tui, ncurses, enterprise-clean, compliance, operator-flow
# @PURPOSE: Provide interactive ncurses-compatible TUI flow for clean release validation and report export.
# @LAYER: UI
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.compliance_orchestrator
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.report_builder
# @INVARIANT: TUI must always expose explicit terminal state READY/RUNNING/COMPLIANT/BLOCKED.
# @UX_STATE: READY -> Candidate and profile are visible; operator can trigger check via hotkey.
# @UX_STATE: RUNNING -> Stage progress is visible with current active check.
# @UX_STATE: COMPLIANT -> Final pass state with report id and export action.
# @UX_STATE: BLOCKED -> Final blocked state with violation table and remediation hints.
# @UX_FEEDBACK: On violation, blocked status is rendered with category/location/remediation.
# @UX_RECOVERY: Operator can fix inputs/config and rerun check from same screen without restarting tool.
# @TEST_CONTRACT: TuiOperatorAction -> TuiStateTransition
# @TEST_FIXTURE: ready_to_running -> {"initial":"READY","action":"F5","expected":"RUNNING"}
# @TEST_EDGE: blocked_due_to_external_source -> {"initial":"RUNNING","result":"external-source violation","expected":"BLOCKED"}
# @TEST_EDGE: internal_registry_unavailable -> {"initial":"RUNNING","error":"internal source unavailable","expected":"BLOCKED"}
# @TEST_EDGE: report_export_without_terminal_state -> export denied before COMPLIANT/BLOCKED
# @TEST_INVARIANT: state_machine_integrity -> VERIFIED_BY: [ready_to_running, blocked_due_to_external_source]
module CleanReleaseTui:
# @PURPOSE: Render main screen and initialize state machine.
# @PRE: Terminal supports ncurses-compatible mode.
# @POST: UI enters READY state with loaded candidate/profile context.
def run(self): ...
# @PURPOSE: Handle key actions (run check, view details, export, exit).
# @PRE: Current UI state exists.
# @POST: Deterministic transition to next valid state.
def handle_input(self): ...
# @PURPOSE: Render progress and status updates from orchestrator.
# @PRE: Check run started.
# @POST: UI reflects latest stage statuses and final result.
def render_status(self): ...
# [/DEF:backend.src.scripts.clean_release_tui:Module]
---
# [DEF:backend.src.api.routes.clean_release:Module]
# @TIER: STANDARD
# @SEMANTICS: api, clean-release, compliance, report, release-gate
# @PURPOSE: Expose release compliance endpoints for CI and controlled integrations.
# @LAYER: API
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.compliance_orchestrator
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.report_builder
# @INVARIANT: API never returns release-approved state when orchestration result is blocked/failed.
module CleanReleaseRouter:
# @PURPOSE: Start compliance check for a candidate.
# @PRE: Candidate exists and caller is authorized.
# @POST: Returns check_run_id and initial RUNNING status.
def start_check(self): ...
# @PURPOSE: Read compliance check status and stage details.
# @PRE: check_run_id exists.
# @POST: Returns deterministic status payload with stage matrix.
def get_check_status(self): ...
# @PURPOSE: Retrieve final compliance report.
# @PRE: check run reached terminal state.
# @POST: Returns report metadata and violations summary.
def get_report(self): ...
# [/DEF:backend.src.api.routes.clean_release:Module]
---
## Contract Trace (Key User Scenario)
Сценарий: оператор запускает TUI-проверку и получает BLOCKED из-за внешнего источника.
1. [`clean_release_tui`](#defbackendsrcscriptsclean_release_tuimodule) принимает `F5` и переводит состояние READY -> RUNNING.
2. [`compliance_orchestrator`](#defbackendsrcservicesclean_releasecompliance_orchestratormodule) запускает stage pipeline.
3. [`policy_engine`](#defbackendsrcservicesclean_releasepolicy_enginemodule) обнаруживает `external-source` нарушение и возвращает fail stage + violation.
4. [`compliance_orchestrator`](#defbackendsrcservicesclean_releasecompliance_orchestratormodule) завершает run статусом BLOCKED.
5. [`report_builder`](#defbackendsrcservicesclean_releasereport_buildermodule) формирует отчёт с remediation.
6. [`clean_release_tui`](#defbackendsrcscriptsclean_release_tuimodule) отображает BLOCKED + таблицу нарушений + путь восстановления.

View File

@@ -0,0 +1,253 @@
# Data Model: Clean Repository Enterprise Preparation
## Overview
Модель данных описывает сущности, необходимые для подготовки и контроля enterprise clean-поставки в изолированном контуре без внешнего интернета.
---
## 1) ReleaseCandidate
**Purpose**: Представляет конкретный релиз-кандидат, проходящий clean-подготовку и compliance-проверку.
### Fields
- `candidate_id` (string, required, unique)
Уникальный идентификатор релиз-кандидата.
- `version` (string, required)
Версия/метка релиза.
- `profile` (enum, required)
Допустимые значения: `enterprise-clean`, `development`.
- `created_at` (datetime, required)
- `created_by` (string, required)
Идентификатор оператора/сервиса, создавшего candidate.
- `source_snapshot_ref` (string, required)
Ссылка на исходный снимок/состояние для воспроизводимости.
- `status` (enum, required)
`draft`, `prepared`, `compliant`, `blocked`, `released`.
### Validation Rules
- `candidate_id` и `source_snapshot_ref` не могут быть пустыми.
- Для `profile=enterprise-clean` переход в `released` разрешён только после `compliant`.
- Переходы статусов должны быть монотонными по lifecycle (без недетерминированных откатов).
---
## 2) CleanProfilePolicy
**Purpose**: Формальная политика классификации артефактов и источников ресурсов для enterprise clean-профиля.
### Fields
- `policy_id` (string, required, unique)
- `policy_version` (string, required)
- `active` (boolean, required)
- `prohibited_artifact_categories` (array[string], required)
Примеры: `test-data`, `demo-data`, `load-test`, `sample-repository`.
- `required_system_categories` (array[string], required)
Примеры: `system-init`, `security-bootstrap`, `schema-migrations`.
- `external_source_forbidden` (boolean, required; для enterprise-clean = true)
- `internal_source_registry_ref` (string, required)
Ссылка на реестр внутренних серверов.
- `effective_from` (datetime, required)
- `effective_to` (datetime, optional)
### Validation Rules
- Политика не может быть активирована без `internal_source_registry_ref`.
- Одновременная активность двух политик для одного профиля и периода запрещена.
- Для `enterprise-clean` поле `external_source_forbidden` всегда `true`.
---
## 3) ResourceSourceRegistry
**Purpose**: Реестр разрешённых внутренних серверов компании, используемых для загрузки всех ресурсов.
### Fields
- `registry_id` (string, required, unique)
- `name` (string, required)
- `entries` (array[ResourceSourceEntry], required, min=1)
- `updated_at` (datetime, required)
- `updated_by` (string, required)
- `status` (enum, required)
`active`, `inactive`.
### ResourceSourceEntry (nested)
- `source_id` (string, required, unique within registry)
- `host` (string, required)
- `protocol` (enum, required)
`http`, `https`, `ssh`, `file`.
- `purpose` (string, required)
Например: `artifact-repo`, `package-mirror`, `git-mirror`.
- `allowed_paths` (array[string], optional)
- `enabled` (boolean, required)
### Validation Rules
- В `entries` запрещены дубликаты `host + purpose`.
- При `status=active` должен существовать хотя бы один `enabled=true` entry.
- Внешние публичные хосты не допускаются в активном реестре enterprise clean-профиля.
---
## 4) DistributionManifest
**Purpose**: Зафиксированный состав итогового дистрибутива для аудита и воспроизводимости.
### Fields
- `manifest_id` (string, required, unique)
- `candidate_id` (string, required, FK -> ReleaseCandidate)
- `policy_id` (string, required, FK -> CleanProfilePolicy)
- `generated_at` (datetime, required)
- `generated_by` (string, required)
- `items` (array[ManifestItem], required)
- `summary` (ManifestSummary, required)
- `deterministic_hash` (string, required)
### ManifestItem (nested)
- `path` (string, required)
- `category` (string, required)
- `classification` (enum, required)
`required-system`, `allowed`, `excluded-prohibited`.
- `reason` (string, required)
- `checksum` (string, optional for included items)
### ManifestSummary (nested)
- `included_count` (integer, required, >=0)
- `excluded_count` (integer, required, >=0)
- `prohibited_detected_count` (integer, required, >=0)
### Validation Rules
- `candidate_id` и `policy_id` должны ссылаться на существующие записи.
- `deterministic_hash` должен быть одинаковым для идентичного входного состояния.
- `included_count + excluded_count` должно совпадать с размером `items`.
---
## 5) ComplianceCheckRun
**Purpose**: Один запуск проверки соответствия clean/compliance для релиз-кандидата.
### Fields
- `check_run_id` (string, required, unique)
- `candidate_id` (string, required, FK -> ReleaseCandidate)
- `policy_id` (string, required, FK -> CleanProfilePolicy)
- `started_at` (datetime, required)
- `finished_at` (datetime, optional)
- `final_status` (enum, required)
`running`, `compliant`, `blocked`, `failed`.
- `triggered_by` (string, required)
- `execution_mode` (enum, required)
`tui`, `ci`.
- `checks` (array[CheckStageResult], required)
### CheckStageResult (nested)
- `stage` (enum, required)
`data_purity`, `internal_sources_only`, `no_external_endpoints`, `manifest_consistency`.
- `status` (enum, required)
`pass`, `fail`, `skipped`.
- `details` (string, optional)
- `duration_ms` (integer, optional, >=0)
### Validation Rules
- `final_status=compliant` допускается только при `pass` для всех обязательных стадий.
- `final_status=blocked` обязателен при `fail` хотя бы одной обязательной стадии.
- `execution_mode=ci` и `execution_mode=tui` должны быть сопоставимы по policy/version.
---
## 6) ComplianceViolation
**Purpose**: Нормализованная запись конкретного нарушения, найденного в ходе проверки.
### Fields
- `violation_id` (string, required, unique)
- `check_run_id` (string, required, FK -> ComplianceCheckRun)
- `category` (enum, required)
`data-purity`, `external-source`, `manifest-integrity`, `policy-conflict`, `operational-risk`.
- `severity` (enum, required)
`critical`, `high`, `medium`, `low`.
- `location` (string, required)
Путь/endpoint/конфигурационный ключ.
- `evidence` (string, optional)
- `remediation` (string, required)
- `blocked_release` (boolean, required)
- `detected_at` (datetime, required)
### Validation Rules
- Для `category=external-source` поле `blocked_release` всегда `true` в enterprise clean-профиле.
- Для `severity=critical` поле `remediation` обязательно и непустое.
- `check_run_id` должен ссылаться на существующий запуск проверки.
---
## 7) ComplianceReport
**Purpose**: Финальный отчёт проверки для оператора и аудита.
### Fields
- `report_id` (string, required, unique)
- `check_run_id` (string, required, FK -> ComplianceCheckRun)
- `candidate_id` (string, required)
- `generated_at` (datetime, required)
- `operator_summary` (string, required)
- `structured_payload_ref` (string, required)
Ссылка на машинно-читаемое представление.
- `violations_count` (integer, required, >=0)
- `blocking_violations_count` (integer, required, >=0)
### Validation Rules
- `blocking_violations_count``violations_count`.
- При `final_status=blocked` в связанном check run `blocking_violations_count` > 0.
- Отчёт должен быть доступен для экспортирования из TUI сценария.
---
## Relationships
1. `ReleaseCandidate` 1—N `DistributionManifest`
2. `CleanProfilePolicy` 1—N `DistributionManifest`
3. `ReleaseCandidate` 1—N `ComplianceCheckRun`
4. `CleanProfilePolicy` 1—N `ComplianceCheckRun`
5. `ComplianceCheckRun` 1—N `ComplianceViolation`
6. `ComplianceCheckRun` 1—1 `ComplianceReport`
7. `ResourceSourceRegistry` 1—N `CleanProfilePolicy` (по ссылке active policy)
---
## State Model Highlights
### ReleaseCandidate lifecycle
`draft -> prepared -> compliant -> released`
`draft|prepared -> blocked` (при нарушениях)
### ComplianceCheckRun lifecycle
`running -> compliant|blocked|failed`
---
## TUI Mapping Notes (from UX reference)
Состояния TUI из [`ux_reference.md`](./ux_reference.md) напрямую маппятся на сущности:
- `READY` -> `ReleaseCandidate.status in {draft, prepared}`
- `RUNNING` -> `ComplianceCheckRun.final_status = running`
- `COMPLIANT` -> `ComplianceCheckRun.final_status = compliant` + `ComplianceReport`
- `BLOCKED` -> `ComplianceCheckRun.final_status = blocked` + `ComplianceViolation[*].blocked_release=true`

View File

@@ -0,0 +1,170 @@
# Implementation Plan: Clean Repository Enterprise Preparation
**Branch**: `023-clean-repo-enterprise` | **Date**: 2026-03-03 | **Spec**: [`spec.md`](./spec.md)
**Input**: Feature specification from [`/specs/023-clean-repo-enterprise/spec.md`](./spec.md)
## Summary
Подготовить enterprise clean-профиль поставки, который:
1) исключает тестовые/демо-данные из дистрибутива,
2) блокирует любые внешние интернет-источники ресурсов,
3) допускает загрузку ресурсов только с внутренних серверов компании,
4) предоставляет обязательную проверку compliance и аудитный отчёт перед выпуском.
Ключевой UX фиксируется как интерактивный TUI сценарий на основе [`ux_reference.md`](./ux_reference.md): оператор в одном консольном интерфейсе запускает проверку, видит прогресс по этапам, нарушения и итоговый статус (`COMPLIANT`/`BLOCKED`).
## Technical Context
**Language/Version**: Python 3.9+ (backend scripts/services), Shell (release tooling)
**Primary Dependencies**: FastAPI stack (existing backend), ConfigManager, TaskManager, файловые утилиты, internal artifact registries
**Storage**: PostgreSQL (конфигурации/метаданные), filesystem (артефакты дистрибутива, отчёты проверки)
**Testing**: pytest (backend), contract checks для release compliance, smoke checks для TUI flow
**Target Platform**: Linux server в изолированной корпоративной сети
**Project Type**: web-service + operational CLI/TUI tooling
**Performance Goals**:
- стандартный запуск проверки clean/compliance ≤ 15 минут на типовой релиз-кандидат;
- формирование человекочитаемого отчёта сразу после завершения проверки.
**Constraints**:
- Полный запрет на внешние интернет-загрузки в enterprise clean-профиле;
- все ресурсы только с внутренних серверов компании;
- выпуск блокируется при любом нарушении data purity или source isolation.
**Scale/Scope**:
- 1 enterprise release flow;
- 1 TUI сценарий подготовки/проверки;
- 36 новых/обновлённых модулей проверки и отчётности;
- документация и контракты в пределах feature-папки.
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- **I. Semantic Protocol Compliance**: PASS
План предусматривает формальные контракты в [`contracts/modules.md`](./contracts/modules.md) с `[DEF]`/`@TAG` и закрывающими якорями.
- **II. Modular Plugin Architecture**: PASS
Логика будет интегрирована через существующие сервисы/плагины и централизованную конфигурацию через `ConfigManager`; hardcode-источники запрещаются политикой clean-profile.
- **III. Unified Frontend Experience**: PASS (N/A for web UI changes)
Для фичи primary UX — TUI (`ncurses`-совместимый). Изменений веб-компонентов, нарушающих правила `requestApi/fetchApi`, не планируется.
- **IV. Security & RBAC**: PASS
Проверка соответствия и выпускные действия остаются под существующей auth/RBAC моделью и аудитом.
- **V. Independent Testability**: PASS
В спецификации определены независимые пользовательские сценарии с отдельной проверяемостью.
- **VI. Asynchronous Execution**: PASS
Длительная проверка может быть оформлена как task-flow с отчётом; блокировок API на долгих операциях не планируется.
**Gate Result (pre-research)**: PASS
## Project Structure
### Documentation (this feature)
```text
specs/023-clean-repo-enterprise/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ ├── modules.md
│ └── api.yaml
└── tasks.md
```
### Source Code (repository root)
```text
backend/
├── src/
│ ├── api/
│ ├── core/
│ ├── services/
│ └── scripts/
└── tests/
frontend/
└── src/ # Без изменений в рамках этой фичи (primary UX = TUI script)
```
**Structure Decision**: Выбрана структура web application с упором на backend + operational TUI tooling; изменения фронтенда не требуются для MVP enterprise clean-подготовки.
## Phase 0 — Outline & Research Plan
Цель: снять неопределённости и принять архитектурные решения до контрактов.
Исследовательские направления:
1. Политика классификации артефактов (что считать test/demo/load data и как исключать без повреждения system-init).
2. Политика source isolation (детекция и запрет внешних internet endpoints, allowlist внутренних серверов).
3. Формат compliance-отчёта для релизного аудита (минимальный обязательный набор полей).
4. Паттерн интеграции TUI-проверки в существующий release workflow (ручной запуск + CI gate).
Выход Phase 0: заполненный [`research.md`](./research.md) без `NEEDS CLARIFICATION`.
## Phase 1 — Design & Contracts Plan
Цель: спроектировать сущности, контракты и API/интерфейсы для реализации.
1. Проверка соответствия UX из [`ux_reference.md`](./ux_reference.md):
- состояния `READY/RUNNING/COMPLIANT/BLOCKED` должны быть отражены в контракте TUI-модуля (`@UX_STATE`);
- ошибки `Data Purity`, `External Source`, `Internal Source Unavailable` должны иметь контракт восстановления.
2. Модель данных:
- ReleaseCandidate, CleanProfilePolicy, ResourceSourceRegistry, ComplianceCheckReport, DistributionManifest.
3. Семантические контракты:
- модуль orchestration проверки;
- модуль policy engine;
- модуль source isolation validator;
- модуль report generator;
- TUI module (CRITICAL UX-contract).
4. API/контракты:
- схема запуска проверки и получения результата;
- контракт структуры violation entries.
5. Quickstart:
- изолированный запуск в корпоративной сети без внешнего интернета.
Выход Phase 1:
- [`data-model.md`](./data-model.md)
- [`contracts/modules.md`](./contracts/modules.md)
- [`contracts/api.yaml`](./contracts/api.yaml)
- [`quickstart.md`](./quickstart.md)
## Phase 2 — Task Planning Approach
На этапе `/speckit.tasks` задачи будут разбиты на независимые user-story инкременты:
- US1 (P1): формирование clean-дистрибутива без test/demo-data.
- US2 (P1): source isolation и internal-only resource policy.
- US3 (P2): release compliance gate + отчётность.
- US4 (P3): операционный runbook + onboarding сценарий.
Для каждой истории будут определены:
- независимый тест;
- набор backend задач;
- проверка контракта;
- критерии готовности.
## Post-Design Constitution Re-Check
Проверка после подготовки артефактов Phase 1 ([`research.md`](./research.md), [`data-model.md`](./data-model.md), [`contracts/modules.md`](./contracts/modules.md), [`contracts/api.yaml`](./contracts/api.yaml), [`quickstart.md`](./quickstart.md)):
- **I. Semantic Protocol Compliance**: PASS
Контракты оформлены через `[DEF:...:Module]` и закрывающие `[/DEF:...:Module]` в [`contracts/modules.md`](./contracts/modules.md).
- **II. Modular Plugin Architecture**: PASS
Дизайн опирается на существующие модульные сервисы и централизованную конфигурацию, без hardcode-конфигураций clean-политики.
- **III. Unified Frontend Experience**: PASS (N/A for web UI changes)
Целевой UX реализуется как TUI (`ncurses`-совместимый), что согласовано со [`ux_reference.md`](./ux_reference.md).
- **IV. Security & RBAC**: PASS
Введён блокирующий compliance-gate при внешних источниках и запрещённых данных, отчётность предусмотрена для аудита.
- **V. Independent Testability**: PASS
Зафиксированы независимые сценарии проверки clean/compliance и recovery flow в [`quickstart.md`](./quickstart.md).
- **VI. Asynchronous Execution**: PASS
Длительная проверка проектируется как orchestrated run с поэтапным статусом и финальным отчётом, без требований к блокирующим long-running API вызовам.
**Gate Result (post-design)**: PASS
**Operational Note**: в tooling обнаружено предупреждение о конфликте numeric prefix `020` между [`specs/023-clean-repo-enterprise`](./) и [`specs/020-task-reports-design`](../020-task-reports-design). Это не блокирует текущий план-файл, но требует governance-решения для устранения неоднозначности при запуске стандартных `speckit`-скриптов.
## Complexity Tracking
> Fill ONLY if Constitution Check has violations that must be justified
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| None at planning stage | N/A | N/A |

View File

@@ -0,0 +1,108 @@
# Quickstart: Enterprise Clean Compliance (TUI)
## Purpose
Этот quickstart описывает минимальный операционный путь проверки enterprise clean-поставки в изолированной сети компании:
- без внешнего интернета;
- только с внутренними серверами ресурсов;
- с блокировкой релиза при нарушениях.
## Prerequisites
1. Есть релиз-кандидат (`candidate_id`) для проверки.
2. Активна политика `enterprise-clean`.
3. Настроен внутренний реестр серверов ресурсов (artifact/git/package mirrors).
4. Внешний интернет для узла проверки недоступен/запрещён согласно корпоративной политике.
5. Доступен TUI-скрипт проверки clean-compliance.
## Step 1 — Запуск TUI
```bash
cd /home/busya/dev/ss-tools
./backend/.venv/bin/python3 -m backend.src.scripts.clean_release_tui
```
Ожидаемое состояние интерфейса после старта: `READY`.
## Step 2 — Выбор релиз-кандидата и профиля
В главном экране TUI:
1. Установить `Candidate = <candidate_id>`.
2. Установить `Profile = enterprise-clean`.
3. Проверить, что отображается список разрешённых внутренних серверов.
## Step 3 — Запуск проверки
Нажать `F5` (Run Check).
Ожидаемый порядок стадий:
1. `Data Purity`
2. `Internal Sources Only`
3. `No External Internet Endpoints`
4. `Manifest Consistency`
Состояние интерфейса: `RUNNING`.
## Step 4A — Успешный результат
Если все стадии `PASS`:
- итоговый статус: `COMPLIANT`;
- отображается `Report ID`;
- доступна выгрузка отчёта (`F6 Export Report`).
Это означает, что релиз-кандидат допускается к следующему этапу выпуска.
## Step 4B — Блокирующий результат
Если хотя бы одна обязательная стадия `FAIL`:
- итоговый статус: `BLOCKED`;
- отображается таблица нарушений с полями:
- категория;
- локация;
- remediation.
Типовые причины:
- найдены test/demo/load-test данные;
- найден внешний endpoint;
- нарушена целостность manifest.
## Step 5 — Recovery Flow
1. Исправить нарушения по рекомендациям в отчёте.
2. Повторно запустить проверку из того же TUI экрана (`F5`).
3. Повторять до статуса `COMPLIANT`.
## CI Gate (обязательный)
После операторского прогона TUI та же политика должна быть проверена в CI.
Релиз допускается только при `COMPLIANT` в CI-прогоне.
## Acceptance Checklist (Operator)
- [ ] Проверка выполнена на профиле `enterprise-clean`
- [ ] Внешние источники не обнаружены
- [ ] Проверка завершена статусом `COMPLIANT`
- [ ] Отчёт выгружен и приложен к релизному пакету
- [ ] Candidate отмечен как готовый к выпуску
## Troubleshooting
### Сценарий: Internal source unavailable
Симптом:
- этап `Internal Sources Only` или `No External Internet Endpoints` завершился с ошибкой доступности.
Действия:
1. Проверить доступность внутреннего сервера ресурсов.
2. Проверить соответствие endpoint реестру разрешённых источников.
3. Перезапустить проверку.
### Сценарий: External source detected
Симптом:
- в нарушениях категория `external-source`.
Действия:
1. Удалить/заменить внешний источник на внутренний сервер из реестра.
2. Подтвердить изменение конфигурации.
3. Перезапустить проверку.

View File

@@ -0,0 +1,131 @@
# Phase 0 Research: Clean Repository Enterprise Preparation
## Decision 1: Артефакты разделяются на 3 класса политики clean-профиля
**Decision**
Ввести формальную классификацию артефактов при подготовке enterprise clean-поставки:
1. **Prohibited Artifacts** — строго запрещены (test/demo/load-test payloads, примеры эксплуатационных данных, временные дампы и нецелевые локальные БД/репозитории).
2. **Required System Artifacts** — обязательны для работоспособного старта (системная инициализация, базовые конфигурации, служебные миграции, security bootstrap).
3. **Conditional Artifacts** — допускаются только при соблюдении дополнительных условий (например, шаблоны конфигурации без чувствительных данных).
**Rationale**
Проблема clean-подготовки не решается простым delete-list: есть риск удалить необходимые для запуска системные элементы. Разделение на 3 класса даёт детерминированную и проверяемую модель принятия решений.
**Alternatives considered**
- **Только deny-list**: отклонено, потому что высок риск ложных блокировок системных стартовых сущностей.
- **Только allow-list**: отклонено как слишком жёсткое для эволюции проекта; высокая операционная стоимость сопровождения без явной пользы на текущем масштабе.
- **Ручная экспертная проверка без формальной модели**: отклонено из-за невоспроизводимости и человеческого фактора.
---
## Decision 2: Source Isolation политика — strict internal-only с явным реестром источников
**Decision**
Для enterprise clean-профиля принять строгую модель source isolation:
- разрешены только источники из **внутреннего реестра серверов компании**;
- любые внешние internet endpoints считаются нарушением и блокируют выпуск;
- отсутствие внешнего интернета трактуется как базовое эксплуатационное условие, а не деградационный режим.
**Rationale**
Требование пользователя и корпоративный контур задают нулевую толерантность к внешним загрузкам. Явный реестр внутренних источников обеспечивает прозрачный аудит и исключает неоднозначную интерпретацию “внутренности” ресурса.
**Alternatives considered**
- **Soft-warning для внешних источников**: отклонено, не соответствует security/compliance профилю.
- **Частично разрешённые внешние зеркала**: отклонено, усложняет доверенную цепочку и нарушает требование полной изоляции.
- **Runtime fallback на внешние источники при недоступности внутренних**: отклонено как прямое нарушение корпоративной политики.
---
## Decision 3: Compliance gate должен быть обязательным и блокирующим перед выпуском
**Decision**
Выпуск enterprise clean-дистрибутива допускается только после обязательной проверки clean/compliance с бинарным результатом:
- `COMPLIANT` — выпуск разрешён;
- `BLOCKED` — выпуск запрещён до устранения нарушений.
Проверка должна валидировать одновременно:
1. data purity (отсутствие запрещённых payloads);
2. source isolation (только внутренние источники);
3. целостность manifest релиза.
**Rationale**
Снижение рисков требует enforce-механизма, а не рекомендаций. Блокирующий gate переводит требования из “договорённостей” в гарантируемый процесс релиза.
**Alternatives considered**
- **Проверка только по запросу**: отклонено из-за неполного охвата релизов.
- **Постфактум аудит после выпуска**: отклонено, потому что не предотвращает инцидент, а фиксирует его постфактум.
- **Частичный gate только по test-data**: отклонено, так как не покрывает критичный риск внешних источников.
---
## Decision 4: UX контроля выпуска — интерактивный TUI (`ncurses`/совместимый аналог)
**Decision**
Операционный интерфейс подготовки/проверки фиксируется как единый интерактивный консольный TUI-flow (на `ncurses` или совместимом аналоге), в котором оператор:
- выбирает релиз-кандидат;
- запускает проверку;
- наблюдает поэтапный прогресс;
- получает итог и детализацию нарушений;
- экспортирует отчёт.
**Rationale**
Для изолированных контуров и release-операций TUI обеспечивает воспроизводимый сценарий без зависимости от веб-интерфейса и внешней инфраструктуры.
**Alternatives considered**
- **Только non-interactive CLI**: отклонено для primary UX из-за более слабой наблюдаемости этапов и восстановительных действий.
- **Веб-панель**: отклонено как нецелевой интерфейс для данной фичи и избыточно для операционного сценария.
---
## Decision 5: Формат compliance-отчёта должен быть одновременно машинным и операторским
**Decision**
Каждый прогон проверки формирует единый отчёт с двумя представлениями:
1. **Structured section** — формализованные поля для автоматической валидации и аудита;
2. **Operator section** — человекочитаемая сводка нарушений и шагов восстановления.
Минимальные поля:
- report_id;
- candidate_id;
- started_at / finished_at;
- final_status;
- checks summary (data purity / internal sources / no external endpoints / manifest consistency);
- violations[] (category, location, severity, remediation);
- execution metadata (кто запустил, профиль, версия политики).
**Rationale**
Без структурированного представления отчёт трудно автоматизировать; без операторской сводки — трудно использовать в day-to-day эксплуатации.
**Alternatives considered**
- **Только текстовый лог**: отклонено, слабая пригодность для автоматического контроля.
- **Только machine format**: отклонено, ухудшает скорость ручного triage в релизном окне.
---
## Decision 6: Интеграция в release workflow — ручной запуск + обязательный CI gate
**Decision**
Использовать двухконтурную интеграцию:
1. **Pre-release operator run (TUI)** — подготовка и предварительная валидация релиз-кандидата;
2. **CI gate** — обязательное повторное подтверждение compliance перед финальным выпуском.
Оба прогона должны опираться на одну и ту же policy-модель.
**Rationale**
Это сочетает управляемость оператора и enforce-гарантию pipeline, снижая риск “локально прошло, в релиз не попало”.
**Alternatives considered**
- **Только операторский запуск**: отклонено (нет централизованной enforce-гарантии).
- **Только CI без операторского шага**: отклонено (хуже диагностика и устранение до релизного окна).
---
## Open Clarifications Status
По итогам Phase 0 `NEEDS CLARIFICATION` не осталось: все критичные решения по scope, security/policy и UX зафиксированы.

View File

@@ -0,0 +1,125 @@
# Feature Specification: Clean Repository Enterprise Preparation
**Feature Branch**: `023-clean-repo-enterprise`
**Created**: 2026-03-03
**Status**: Draft
**Input**: User description: "Я хочу проработать возможность создания чистого репозитория проекта без тестовых данных для последующего разворота в сети моей организации."
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Чистый корпоративный релиз без тестовых данных (Priority: P1)
Как владелец платформы, я хочу получать enterprise-поставку без тестовых и демонстрационных данных, чтобы безопасно разворачивать продукт в сети организации.
**Why this priority**: Это ключевое условие допуска в корпоративный контур и базовое требование к чистоте поставки.
**Independent Test**: Можно сформировать enterprise-дистрибутив и проверить, что запрещённые категории данных отсутствуют, а система запускается в «пустом» рабочем состоянии.
**Acceptance Scenarios**:
1. **Given** собран релиз-кандидат, **When** выполняется подготовка clean-поставки, **Then** итоговый дистрибутив не содержит тестовые и демонстрационные данные.
2. **Given** clean-поставка сформирована, **When** оператор разворачивает её в новом корпоративном окружении, **Then** система стартует без предзагруженных демо-сущностей и доступна для первичной настройки.
---
### User Story 2 - Полностью изолированная поставка без внешнего интернета (Priority: P1)
Как администратор корпоративной инфраструктуры, я хочу, чтобы развёртывание и эксплуатация clean-профиля не требовали внешнего интернета, а все ресурсы загружались только с внутренних серверов компании.
**Why this priority**: Для изолированных контуров это обязательное требование информационной безопасности и комплаенса.
**Independent Test**: Можно отключить внешний интернет для стенда, выполнить установку и запуск, и подтвердить, что все зависимости, артефакты и обновления берутся только из внутренних источников.
**Acceptance Scenarios**:
1. **Given** внешний интернет недоступен, **When** выполняется развертывание clean-профиля, **Then** процесс завершается успешно с использованием только внутренних серверов компании.
2. **Given** в конфигурации указан внешний источник ресурсов, **When** запускается проверка enterprise-compliance, **Then** выпуск блокируется и формируется отчёт о нарушении политики изоляции.
3. **Given** система работает в корпоративной сети, **When** выполняются штатные операции получения ресурсов, **Then** обращения во внешние интернет-источники отсутствуют.
---
### User Story 3 - Обязательная проверка соответствия перед выпуском (Priority: P2)
Как release-менеджер, я хочу иметь обязательный контроль clean/compliance перед выпуском, чтобы исключить случайный выпуск неочищенной или не изолированной поставки.
**Why this priority**: Автоматическая проверка снижает риск человеческой ошибки и обеспечивает повторяемость релизного процесса.
**Independent Test**: Можно подложить запрещённый артефакт или внешний endpoint, запустить проверку и убедиться, что выпуск блокируется с понятным отчётом.
**Acceptance Scenarios**:
1. **Given** в релиз-кандидате найден запрещённый артефакт, **When** запускается проверка соответствия, **Then** проверка завершается неуспешно с детализацией нарушения.
2. **Given** в релиз-кандидате обнаружен внешний источник загрузки ресурсов, **When** запускается проверка соответствия, **Then** проверка завершается неуспешно с указанием внешнего источника и причины блокировки.
3. **Given** релиз-кандидат соответствует правилам clean и изоляции, **When** запускается проверка соответствия, **Then** проверка завершается успешно и фиксируется результат для аудита.
---
### User Story 4 - Прозрачный операционный регламент (Priority: P3)
Как инженер сопровождения, я хочу иметь однозначную документацию по clean-развертыванию в изолированном контуре, чтобы выполнять запуск без дополнительных согласований и устных инструкций.
**Why this priority**: Формализованный регламент уменьшает время ввода в эксплуатацию и число операционных ошибок.
**Independent Test**: Новый инженер по документации выполняет clean-развертывание в изолированном сегменте и проходит проверочный чек-лист без обращения к команде разработки.
**Acceptance Scenarios**:
1. **Given** инженер использует только утверждённую документацию, **When** он выполняет clean-развертывание в изолированной сети, **Then** запуск проходит успешно.
2. **Given** инженер проверяет допустимые источники ресурсов, **When** он сверяется с документацией, **Then** он однозначно определяет, что разрешены только внутренние серверы компании.
---
### Edge Cases
- Что происходит, если обязательные системные стартовые данные ошибочно помечены как тестовые и исключены из clean-поставки?
- Как обрабатывается случай, когда релиз-кандидат одновременно содержит и разрешённые, и запрещённые источники ресурсов?
- Что происходит, если внутренний сервер ресурсов временно недоступен во время развёртывания в изолированном контуре?
- Как система реагирует, если в конфигурации присутствует косвенная ссылка на внешний интернет-источник (например, зеркальный URL вне корпоративного домена)?
- Что происходит при повторной подготовке clean-дистрибутива для уже очищенного релиз-кандидата?
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: Система MUST поддерживать отдельный enterprise clean-профиль поставки для развёртывания без тестовых и демонстрационных данных.
- **FR-002**: Enterprise clean-профиль MUST явно определять запрещённые категории содержимого и применять эти правила при формировании поставки.
- **FR-003**: Процесс формирования clean-дистрибутива MUST исключать запрещённые категории из итогового артефакта, сохраняя минимально необходимый набор для работоспособного запуска.
- **FR-004**: Система MUST обеспечивать режим эксплуатации без зависимости от внешнего интернета для enterprise clean-профиля.
- **FR-005**: Все ресурсы, необходимые для установки, запуска, сопровождения и обновления enterprise clean-профиля, MUST загружаться только с внутренних серверов компании.
- **FR-006**: Система MUST обнаруживать и блокировать внешние интернет-источники ресурсов в релиз-кандидате и операционной конфигурации enterprise clean-профиля.
- **FR-007**: Перед выпуском enterprise clean-дистрибутива MUST выполняться обязательная проверка clean/compliance.
- **FR-008**: Проверка clean/compliance MUST завершаться неуспешно при обнаружении хотя бы одного запрещённого артефакта данных или хотя бы одного внешнего интернет-источника.
- **FR-009**: При неуспешной проверке система MUST формировать отчёт с категорией нарушения, расположением, уровнем критичности и рекомендацией по устранению.
- **FR-010**: При успешной проверке система MUST формировать подтверждение прохождения проверки с идентификатором релиз-кандидата и временем проверки.
- **FR-011**: Процесс clean-подготовки MUST быть воспроизводимым: одинаковое входное состояние должно приводить к одинаковому составу поставки и одинаковому результату проверки.
- **FR-012**: Документация MUST включать отдельный регламент изолированного развертывания, включая требования к внутренним серверам ресурсов и действия при недоступности внутренних источников.
- **FR-013**: Документация MUST чётко разделять сценарии development и enterprise clean, чтобы исключить случайное использование внешних интернет-ресурсов в enterprise-контуре.
- **FR-014**: Система MUST вести аудитный журнал этапов подготовки, проверки и выпуска clean-поставки, включая результаты контроля изоляции от внешнего интернета.
### Key Entities *(include if feature involves data)*
- **Release Candidate**: Набор артефактов, из которого формируется enterprise clean-поставка; содержит идентификатор, версию, временные метки и состав.
- **Clean Profile Policy**: Правила классификации содержимого и источников ресурсов на разрешённые/запрещённые для enterprise clean-профиля.
- **Resource Source Registry**: Формализованный перечень разрешённых внутренних серверов компании для загрузки всех ресурсов.
- **Compliance Check Report**: Результат проверки соответствия с итоговым статусом, списком нарушений, ссылкой на релиз-кандидат и метаданными аудита.
- **Distribution Manifest**: Зафиксированный состав итогового дистрибутива для контроля полноты, воспроизводимости и дальнейшего аудита.
- **Isolated Deployment Runbook**: Документированная операционная последовательность для развертывания и восстановления в изолированном контуре.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: В 100% выпущенных enterprise clean-релизов отсутствуют тестовые и демонстрационные данные в итоговой поставке.
- **SC-002**: В 100% выпущенных enterprise clean-релизов отсутствуют обращения к внешним интернет-источникам ресурсов в процессе установки и запуска.
- **SC-003**: Не менее 95% запусков обязательной проверки соответствия завершаются автоматическим результатом и отчётом без ручного вмешательства.
- **SC-004**: Время подтверждения готовности clean-поставки по утверждённому процессу не превышает 15 минут для стандартного релиз-кандидата.
- **SC-005**: Не менее 90% новых инженеров сопровождения выполняют изолированное clean-развертывание по документации с первой попытки.
- **SC-006**: Количество инцидентов, связанных с попаданием тестовых данных или использованием внешнего интернета в enterprise-контуре, равно нулю в течение первого отчётного квартала после внедрения.
## Assumptions
- Корпоративный контур развёртывания является изолированным и должен работать без доступа к внешнему интернету.
- В организации существуют внутренние серверы для размещения всех необходимых ресурсов поставки и эксплуатации.
- Для продукта допустимо формальное разделение профилей на development и enterprise clean в рамках единого релизного процесса.
- Базовая первичная инициализация системы без демо-данных остаётся обязательной и должна сохраняться в clean-поставке.
- Роли владельца релиза и инженера сопровождения назначены и несут ответственность за прохождение проверок и соблюдение регламента.

View File

@@ -0,0 +1,208 @@
# Tasks: Clean Repository Enterprise Preparation
**Input**: Design documents from `/specs/023-clean-repo-enterprise/`
**Prerequisites**: [`plan.md`](./plan.md), [`spec.md`](./spec.md), [`ux_reference.md`](./ux_reference.md), [`research.md`](./research.md), [`data-model.md`](./data-model.md), [`contracts/`](./contracts)
**Tests**: Тестовые задачи включены выборочно для CRITICAL-контрактов и независимой проверки user stories.
**Organization**: Tasks grouped by user story for independent implementation and validation.
## Format: `[ID] [P?] [Story] Description`
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Подготовка каркаса clean-release подсистемы и мест хранения артефактов.
- [ ] T001 Create feature package skeleton for clean release modules in `backend/src/services/clean_release/__init__.py`
- [ ] T002 [P] Create clean release domain models module in `backend/src/models/clean_release.py`
- [ ] T003 [P] Create clean release API route module placeholder in `backend/src/api/routes/clean_release.py`
- [ ] T004 [P] Create TUI script entrypoint placeholder in `backend/src/scripts/clean_release_tui.py`
- [ ] T005 Register clean release router export in `backend/src/api/routes/__init__.py`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Блокирующие основы, обязательные до user stories.
**⚠️ CRITICAL**: No user story work can begin until this phase is complete.
- [ ] T006 Implement core enums and lifecycle models (`ReleaseCandidate`, `CleanProfilePolicy`, `ResourceSourceRegistry`, `DistributionManifest`, `ComplianceCheckRun`, `ComplianceViolation`, `ComplianceReport`) in `backend/src/models/clean_release.py`
- [ ] T007 [P] Implement persistence adapter for clean release entities in `backend/src/services/clean_release/repository.py`
- [ ] T008 [P] Implement compliance stage constants and run state machine helpers in `backend/src/services/clean_release/stages.py`
- [ ] T009 Wire clean release dependencies provider in `backend/src/dependencies.py`
- [ ] T010 Add API router include for clean release endpoints in `backend/src/app.py`
- [ ] T011 Add baseline fixtures for clean release policy/candidate/report payloads in `backend/tests/fixtures/clean_release/fixtures_clean_release.json`
**Checkpoint**: Foundation ready — user story implementation can now begin.
---
## Phase 3: User Story 1 - Чистый корпоративный релиз без тестовых данных (Priority: P1) 🎯 MVP
**Goal**: Формировать enterprise clean-дистрибутив без test/demo payloads с детерминированным manifest.
**Independent Test**: На одном релиз-кандидате с тестовыми артефактами получить `excluded-prohibited`, на чистом — получить manifest без запрещённых категорий.
### Tests for User Story 1
- [ ] T012 [P] [US1] Add unit tests for artifact classification and deterministic decisions in `backend/tests/services/clean_release/test_policy_engine.py`
- [ ] T013 [P] [US1] Add integration test for manifest generation consistency in `backend/tests/services/clean_release/test_manifest_builder.py`
### Implementation for User Story 1
- [ ] T014 [US1] Implement `CleanPolicyEngine` (CRITICAL: PRE: active policy + valid registry; POST: classification in [required-system|allowed|excluded-prohibited]; TESTS: fixture `policy_enterprise_clean`, edges `conflicting_rules`/`missing_registry`/`empty_prohibited_categories`) in `backend/src/services/clean_release/policy_engine.py`
- [ ] T015 [US1] Implement distribution manifest builder and deterministic hash logic in `backend/src/services/clean_release/manifest_builder.py`
- [ ] T016 [US1] Implement release candidate preparation service flow in `backend/src/services/clean_release/preparation_service.py`
- [ ] T017 [US1] Expose candidate preparation API handler in `backend/src/api/routes/clean_release.py`
- [ ] T018 [US1] Verify implementation matches `ux_reference.md` (Happy Path & Errors) in `specs/023-clean-repo-enterprise/ux_reference.md`
**Checkpoint**: US1 independently functional and testable.
---
## Phase 4: User Story 2 - Полностью изолированная поставка без внешнего интернета (Priority: P1)
**Goal**: Гарантировать strict internal-only source policy и блокировать внешние endpoints.
**Independent Test**: При наличии внешнего endpoint выпуск блокируется; при internal-only источниках этап source isolation проходит.
### Tests for User Story 2
- [ ] T019 [P] [US2] Add unit tests for internal source registry validation in `backend/tests/services/clean_release/test_source_isolation.py`
- [ ] T020 [P] [US2] Add integration test for external endpoint blocking in `backend/tests/api/routes/test_clean_release_source_policy.py`
### Implementation for User Story 2
- [ ] T021 [US2] Implement source isolation validator service in `backend/src/services/clean_release/source_isolation.py`
- [ ] T022 [US2] Extend `CleanPolicyEngine` with source registry checks for external endpoint detection in `backend/src/services/clean_release/policy_engine.py`
- [ ] T023 [US2] Add source registry API contract handling (`internal-only` validation errors) in `backend/src/api/routes/clean_release.py`
- [ ] T024 [US2] Update TUI view model to display Allowed Internal Sources panel and External Source blocking messages in `backend/src/scripts/clean_release_tui.py`
- [ ] T025 [US2] Verify implementation matches `ux_reference.md` (Happy Path & Errors) in `specs/023-clean-repo-enterprise/ux_reference.md`
**Checkpoint**: US2 independently functional and testable.
---
## Phase 5: User Story 3 - Обязательная проверка соответствия перед выпуском (Priority: P2)
**Goal**: Реализовать обязательный blocking compliance gate с отчётностью для аудита.
**Independent Test**: Запуск проверки возвращает `COMPLIANT` только при pass всех обязательных стадий; иначе `BLOCKED` с violation details.
### Tests for User Story 3
- [ ] T026 [P] [US3] Add orchestrator state machine tests for stage pass/fail transitions in `backend/tests/services/clean_release/test_compliance_orchestrator.py`
- [ ] T027 [P] [US3] Add report builder validation tests for counters and blocking violations in `backend/tests/services/clean_release/test_report_builder.py`
- [ ] T028 [P] [US3] Add API contract tests for `/api/clean-release/checks*` and `/api/clean-release/reports/{id}` in `backend/tests/api/routes/test_clean_release_api.py`
### Implementation for User Story 3
- [ ] T029 [US3] Implement `CleanComplianceOrchestrator` (CRITICAL: PRE: candidate exists + active policy; POST: final status COMPLIANT/BLOCKED/FAILED; TESTS: fixture `compliant_candidate`, edges `stage_failure_blocks_release`/`missing_stage_result`/`report_generation_error`) in `backend/src/services/clean_release/compliance_orchestrator.py`
- [ ] T030 [US3] Implement `ComplianceReportBuilder` (CRITICAL: PRE: terminal run state; POST: report counters consistent with violations; TESTS: fixture `blocked_with_two_violations`, edges `empty_violations_for_blocked`/`counter_mismatch`/`missing_operator_summary`) in `backend/src/services/clean_release/report_builder.py`
- [ ] T031 [US3] Implement clean release API endpoints from `contracts/api.yaml` in `backend/src/api/routes/clean_release.py`
- [ ] T032 [US3] Add audit logging hooks for preparation/check/report lifecycle in `backend/src/services/clean_release/audit_service.py`
- [ ] T033 [US3] Verify implementation matches `ux_reference.md` (Happy Path & Errors) in `specs/023-clean-repo-enterprise/ux_reference.md`
**Checkpoint**: US3 independently functional and testable.
---
## Phase 6: User Story 4 - Прозрачный операционный регламент (Priority: P3)
**Goal**: Обеспечить воспроизводимый runbook для операторов и onboarding без устных договорённостей.
**Independent Test**: Новый инженер выполняет сценарий только по документации и получает валидный результат проверки.
### Implementation for User Story 4
- [ ] T034 [US4] Update operator runbook with enterprise clean lifecycle and recovery actions in `docs/installation.md`
- [ ] T035 [US4] Add dedicated enterprise clean deployment section with internal-only source policy in `README.md`
- [ ] T036 [US4] Sync quick operational guidance with compliance statuses and report workflow in `specs/023-clean-repo-enterprise/quickstart.md`
- [ ] T037 [US4] Add troubleshooting matrix for blocked categories (`data-purity`, `external-source`, `operational-risk`) in `specs/023-clean-repo-enterprise/quickstart.md`
- [ ] T038 [US4] Verify implementation matches `ux_reference.md` (Happy Path & Errors) in `specs/023-clean-repo-enterprise/ux_reference.md`
**Checkpoint**: US4 independently functional and testable.
---
## Phase 7: Polish & Cross-Cutting Concerns
**Purpose**: Финализация, smoke-проверки и governance-замыкание.
- [ ] T039 [P] Run end-to-end smoke validation of TUI scenario from `quickstart.md` and record results in `specs/023-clean-repo-enterprise/quickstart.md`
- [ ] T040 [P] Validate OpenAPI contract consistency against implemented routes in `backend/tests/api/routes/test_clean_release_api.py`
- [ ] T041 Add release checklist artifact template for compliance evidence packaging in `specs/023-clean-repo-enterprise/checklists/release-readiness.md`
- [ ] T042 Resolve numeric-prefix governance conflict note (`020-*`) and document decision in `specs/023-clean-repo-enterprise/plan.md`
- [ ] T043 Update feature status traceability and final notes in `specs/023-clean-repo-enterprise/plan.md`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Phase 1 (Setup)**: Start immediately.
- **Phase 2 (Foundational)**: Depends on Phase 1 — blocks all stories.
- **Phase 3 (US1)**: Depends on Phase 2.
- **Phase 4 (US2)**: Depends on Phase 2; can run in parallel with US1 if staffed.
- **Phase 5 (US3)**: Depends on Phase 2 and outputs from US1/US2.
- **Phase 6 (US4)**: Depends on stable outputs from US1US3.
- **Phase 7 (Polish)**: Depends on all selected user stories complete.
### User Story Dependencies
- **US1 (P1)**: Independent after foundation.
- **US2 (P1)**: Independent after foundation, integrates with US1 policy artifacts.
- **US3 (P2)**: Uses services from US1/US2 for full compliance gate.
- **US4 (P3)**: Depends on finalized behavior from US1US3.
### Parallel Opportunities
- Phase 1 tasks marked [P]: T002, T003, T004.
- Phase 2 tasks marked [P]: T007, T008.
- US1 tests T012/T013 parallel.
- US2 tests T019/T020 parallel.
- US3 tests T026/T027/T028 parallel.
- Polish tasks T039/T040 parallel.
---
## Parallel Example: User Story 2
```bash
# Parallel test implementation
Task: "T019 [US2] Add unit tests for internal source registry validation in backend/tests/services/clean_release/test_source_isolation.py"
Task: "T020 [US2] Add integration test for external endpoint blocking in backend/tests/api/routes/test_clean_release_source_policy.py"
# Parallel implementation after tests
Task: "T021 [US2] Implement source isolation validator service in backend/src/services/clean_release/source_isolation.py"
Task: "T024 [US2] Update TUI view model for Allowed Internal Sources and blocking messages in backend/src/scripts/clean_release_tui.py"
```
---
## Implementation Strategy
### MVP First (US1)
1. Complete Phase 1 + Phase 2.
2. Deliver Phase 3 (US1) completely.
3. Validate US1 independently (clean distribution without test/demo data).
4. Demo MVP.
### Incremental Delivery
1. US1 (clean artifacts)
2. US2 (strict internal-only sources)
3. US3 (blocking compliance gate + reports)
4. US4 (operational runbook and onboarding)
5. Polish and governance closure.
### UX Preservation Check
- Tasks explicitly preserve TUI/ncurses interaction model from [`ux_reference.md`](./ux_reference.md).
- No task introduces web UI replacement for the primary operator flow.
- Each user story phase contains a mandatory UX conformance verification task.

View File

@@ -0,0 +1,116 @@
# UX Reference: Clean Repository Enterprise Preparation
**Feature Branch**: `023-clean-repo-enterprise`
**Created**: 2026-03-03
**Status**: Draft
## 1. User Persona & Context
* **Who is the user?**: Release Manager и инженер сопровождения корпоративной платформы.
* **What is their goal?**: Подготовить и выпустить clean-дистрибутив без тестовых данных и без зависимости от внешнего интернета.
* **Context**: Работа в изолированной сети организации.
* **Interaction Model (explicit)**: Пользовательский интерфейс реализуется как **интерактивный консольный TUI-скрипт на базе `ncurses` (или полностью совместимого аналога)**. Веб-интерфейс для этого сценария не является целевым.
## 2. The "Happy Path" Narrative
Оператор запускает TUI-скрипт и видит главный экран подготовки enterprise clean-релиза. В форме выбирается релиз-кандидат и профиль `enterprise-clean`, затем запускается проверка одной горячей клавишей. На экране в реальном времени обновляются этапы проверки: чистота данных, проверка источников ресурсов и изоляция от внешнего интернета. После завершения пользователь получает итоговый статус `COMPLIANT`, ID отчёта и короткую сводку для передачи в релизный процесс. Весь путь проходится в одном ncurses-экране без переходов во внешние инструменты.
## 3. Interface Mockups
### CLI Interaction (TUI / ncurses)
```bash
$ clean-release-tui
```
```text
┌──────────────────────────────────────────────────────────────────────────────┐
│ Enterprise Clean Release Validator (TUI) │
├──────────────────────────────────────────────────────────────────────────────┤
│ Candidate: [2026.03.03-rc1 ] Profile: [enterprise-clean]│
│ │
│ Checks: │
│ [ ] Data Purity (no test/demo payloads) │
│ [ ] Internal Sources Only (company servers) │
│ [ ] No External Internet Endpoints │
│ [ ] Release Manifest Consistency │
│ │
│ Allowed Internal Sources: │
│ - repo.intra.company.local │
│ - artifacts.intra.company.local │
│ - pypi.intra.company.local │
│ │
│ Status: READY │
├──────────────────────────────────────────────────────────────────────────────┤
│ F5 Run Check F6 Export Report F10 Exit │
└──────────────────────────────────────────────────────────────────────────────┘
```
```text
┌──────────────────────────────────────────────────────────────────────────────┐
│ Check Progress │
├──────────────────────────────────────────────────────────────────────────────┤
│ [1/4] Data Purity................................. PASS │
│ [2/4] Internal Sources Only....................... PASS │
│ [3/4] No External Internet Endpoints.............. PASS │
│ [4/4] Manifest Consistency........................ PASS │
│ │
│ FINAL STATUS: COMPLIANT │
│ Report ID: CCR-2026-03-03-001 │
├──────────────────────────────────────────────────────────────────────────────┤
│ Enter View Details F6 Export Report F10 Exit │
└──────────────────────────────────────────────────────────────────────────────┘
```
### UI Layout & Flow (for TUI screen states)
**Screen/Component**: Main ncurses validation screen
* **Layout**:
* Верхний блок: выбор релиз-кандидата и профиля.
* Средний блок: список проверок и прогресс.
* Нижний блок: журнал сообщений/ошибок и подсказки горячих клавиш.
* **Key Elements**:
* **Candidate Field**: выбор проверяемого релиз-кандидата.
* **Profile Field**: фиксированное значение `enterprise-clean`.
* **Allowed Sources Panel**: видимый список допустимых внутренних серверов.
* **Violations Table (details mode)**: нарушения с категорией, путём и рекомендацией.
* **States**:
* **Default**: готовность к запуску проверки.
* **Running**: поэтапный прогресс проверок.
* **Compliant**: успешное завершение и экспорт отчёта.
* **Blocked**: выпуск заблокирован до устранения нарушений.
## 4. The "Error" Experience
**Philosophy**: Ошибка должна блокировать выпуск и сразу показывать конкретное нарушение и путь исправления в терминах релизного процесса.
### Scenario A: Найдены тестовые/демо-данные
* **User Action**: Нажимает `F5 Run Check`.
* **System Response (TUI)**:
* Итог: `FINAL STATUS: BLOCKED`
* Запись в деталях: `Category=Data Purity`, `Path=<artifact-path>`, `Action=Remove prohibited content`
* **Recovery**: Удалить артефакты, повторно запустить проверку из того же экрана.
### Scenario B: Найден внешний источник ресурсов
* **System Response (TUI)**:
* Итог: `FINAL STATUS: BLOCKED`
* Запись в деталях: `Category=External Source`, `Endpoint=<external-host>`, `Action=Replace with approved internal server`
* **Recovery**: Заменить источник на внутренний из реестра разрешённых, затем повторить проверку.
### Scenario C: Недоступен внутренний сервер ресурсов
* **System Response (TUI)**:
* Этап помечается как `FAILED: Internal source unavailable`
* Итог: `BLOCKED (operational risk)`
* **Recovery**: Восстановить доступность внутреннего сервера и перезапустить проверку (F5).
## 5. Tone & Voice
* **Style**: Операционный, короткий, однозначный.
* **Terminology**:
* Использовать: «enterprise clean-профиль», «релиз-кандидат», «внутренний сервер», «блокировка выпуска».
* Не использовать размытые формулировки вроде «возможно» или «вероятно».
* В сообщениях о нарушениях указывать: категорию, объект, действие для исправления.