diff --git a/specs/023-clean-repo-enterprise/checklists/requirements.md b/specs/023-clean-repo-enterprise/checklists/requirements.md new file mode 100644 index 0000000..165bc9c --- /dev/null +++ b/specs/023-clean-repo-enterprise/checklists/requirements.md @@ -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). \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/contracts/api.yaml b/specs/023-clean-repo-enterprise/contracts/api.yaml new file mode 100644 index 0000000..51456c9 --- /dev/null +++ b/specs/023-clean-repo-enterprise/contracts/api.yaml @@ -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' \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/contracts/modules.md b/specs/023-clean-repo-enterprise/contracts/modules.md new file mode 100644 index 0000000..32191ce --- /dev/null +++ b/specs/023-clean-repo-enterprise/contracts/modules.md @@ -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 + таблицу нарушений + путь восстановления. \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/data-model.md b/specs/023-clean-repo-enterprise/data-model.md new file mode 100644 index 0000000..5f6cf81 --- /dev/null +++ b/specs/023-clean-repo-enterprise/data-model.md @@ -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` \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/plan.md b/specs/023-clean-repo-enterprise/plan.md new file mode 100644 index 0000000..f0a4d3c --- /dev/null +++ b/specs/023-clean-repo-enterprise/plan.md @@ -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 сценарий подготовки/проверки; +- 3–6 новых/обновлённых модулей проверки и отчётности; +- документация и контракты в пределах 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 | diff --git a/specs/023-clean-repo-enterprise/quickstart.md b/specs/023-clean-repo-enterprise/quickstart.md new file mode 100644 index 0000000..2d31625 --- /dev/null +++ b/specs/023-clean-repo-enterprise/quickstart.md @@ -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 = `. +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. Перезапустить проверку. \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/research.md b/specs/023-clean-repo-enterprise/research.md new file mode 100644 index 0000000..42bdc10 --- /dev/null +++ b/specs/023-clean-repo-enterprise/research.md @@ -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 зафиксированы. \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/spec.md b/specs/023-clean-repo-enterprise/spec.md new file mode 100644 index 0000000..7e71857 --- /dev/null +++ b/specs/023-clean-repo-enterprise/spec.md @@ -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-поставке. +- Роли владельца релиза и инженера сопровождения назначены и несут ответственность за прохождение проверок и соблюдение регламента. diff --git a/specs/023-clean-repo-enterprise/tasks.md b/specs/023-clean-repo-enterprise/tasks.md new file mode 100644 index 0000000..a58bad1 --- /dev/null +++ b/specs/023-clean-repo-enterprise/tasks.md @@ -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 US1–US3. +- **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 US1–US3. + +### 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. \ No newline at end of file diff --git a/specs/023-clean-repo-enterprise/ux_reference.md b/specs/023-clean-repo-enterprise/ux_reference.md new file mode 100644 index 0000000..0791e1e --- /dev/null +++ b/specs/023-clean-repo-enterprise/ux_reference.md @@ -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=`, `Action=Remove prohibited content` +* **Recovery**: Удалить артефакты, повторно запустить проверку из того же экрана. + +### Scenario B: Найден внешний источник ресурсов + +* **System Response (TUI)**: + * Итог: `FINAL STATUS: BLOCKED` + * Запись в деталях: `Category=External Source`, `Endpoint=`, `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-профиль», «релиз-кандидат», «внутренний сервер», «блокировка выпуска». + * Не использовать размытые формулировки вроде «возможно» или «вероятно». + * В сообщениях о нарушениях указывать: категорию, объект, действие для исправления. \ No newline at end of file