# 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 + таблицу нарушений + путь восстановления.