# [DEF:backend.src.services.clean_release.compliance_execution_service:Module] # @TIER: CRITICAL # @SEMANTICS: clean-release, compliance, execution, stages, immutable-evidence # @PURPOSE: Create and execute compliance runs with trusted snapshots, deterministic stages, violations and immutable report persistence. # @LAYER: Domain # @RELATION: DEPENDS_ON -> backend.src.services.clean_release.repository # @RELATION: DEPENDS_ON -> backend.src.services.clean_release.policy_resolution_service # @RELATION: DEPENDS_ON -> backend.src.services.clean_release.stages # @RELATION: DEPENDS_ON -> backend.src.services.clean_release.report_builder # @INVARIANT: A run binds to exactly one candidate/manifest/policy/registry snapshot set. from __future__ import annotations from dataclasses import dataclass from datetime import datetime, timezone from typing import Any, Iterable, List, Optional from uuid import uuid4 from ...core.logger import belief_scope, logger from ...models.clean_release import ComplianceReport, ComplianceRun, ComplianceStageRun, ComplianceViolation, DistributionManifest from .audit_service import audit_check_run, audit_report, audit_violation from .enums import ComplianceDecision, RunStatus from .exceptions import ComplianceRunError, PolicyResolutionError from .policy_resolution_service import resolve_trusted_policy_snapshots from .report_builder import ComplianceReportBuilder from .repository import CleanReleaseRepository from .stages import build_default_stages, derive_final_status from .stages.base import ComplianceStage, ComplianceStageContext, build_stage_run_record # [DEF:ComplianceExecutionResult:Class] # @PURPOSE: Return envelope for compliance execution with run/report and persisted stage artifacts. @dataclass class ComplianceExecutionResult: run: ComplianceRun report: Optional[ComplianceReport] stage_runs: List[ComplianceStageRun] violations: List[ComplianceViolation] # [/DEF:ComplianceExecutionResult:Class] # [DEF:ComplianceExecutionService:Class] # @PURPOSE: Execute clean-release compliance lifecycle over trusted snapshots and immutable evidence. # @PRE: repository and config_manager are initialized. # @POST: run state, stage records, violations and optional report are persisted consistently. class ComplianceExecutionService: TASK_PLUGIN_ID = "clean-release-compliance" def __init__( self, *, repository: CleanReleaseRepository, config_manager, stages: Optional[Iterable[ComplianceStage]] = None, ): self.repository = repository self.config_manager = config_manager self.stages = list(stages) if stages is not None else build_default_stages() self.report_builder = ComplianceReportBuilder(repository) # [DEF:_resolve_manifest:Function] # @PURPOSE: Resolve explicit manifest or fallback to latest candidate manifest. # @PRE: candidate exists. # @POST: Returns manifest snapshot or raises ComplianceRunError. def _resolve_manifest(self, candidate_id: str, manifest_id: Optional[str]) -> DistributionManifest: with belief_scope("ComplianceExecutionService._resolve_manifest"): if manifest_id: manifest = self.repository.get_manifest(manifest_id) if manifest is None: raise ComplianceRunError(f"manifest '{manifest_id}' not found") if manifest.candidate_id != candidate_id: raise ComplianceRunError("manifest does not belong to candidate") return manifest manifests = self.repository.get_manifests_by_candidate(candidate_id) if not manifests: raise ComplianceRunError(f"candidate '{candidate_id}' has no manifest") return sorted(manifests, key=lambda item: item.manifest_version, reverse=True)[0] # [/DEF:_resolve_manifest:Function] # [DEF:_persist_stage_run:Function] # @PURPOSE: Persist stage run if repository supports stage records. # @POST: Stage run is persisted when adapter is available, otherwise no-op. def _persist_stage_run(self, stage_run: ComplianceStageRun) -> None: if hasattr(self.repository, "save_stage_run"): self.repository.save_stage_run(stage_run) # [/DEF:_persist_stage_run:Function] # [DEF:_persist_violations:Function] # @PURPOSE: Persist stage violations via repository adapters. # @POST: Violations are appended to repository evidence store. def _persist_violations(self, violations: List[ComplianceViolation]) -> None: for violation in violations: self.repository.save_violation(violation) # [/DEF:_persist_violations:Function] # [DEF:execute_run:Function] # @PURPOSE: Execute compliance run stages and finalize immutable report on terminal success. # @PRE: candidate exists and trusted policy/registry snapshots are resolvable. # @POST: Run and evidence are persisted; report exists for SUCCEEDED runs. def execute_run( self, *, candidate_id: str, requested_by: str, manifest_id: Optional[str] = None, ) -> ComplianceExecutionResult: with belief_scope("ComplianceExecutionService.execute_run"): logger.reason(f"Starting compliance execution candidate_id={candidate_id}") candidate = self.repository.get_candidate(candidate_id) if candidate is None: raise ComplianceRunError(f"candidate '{candidate_id}' not found") manifest = self._resolve_manifest(candidate_id, manifest_id) try: policy_snapshot, registry_snapshot = resolve_trusted_policy_snapshots( config_manager=self.config_manager, repository=self.repository, ) except PolicyResolutionError as exc: raise ComplianceRunError(str(exc)) from exc run = ComplianceRun( id=f"run-{uuid4()}", candidate_id=candidate_id, manifest_id=manifest.id, manifest_digest=manifest.manifest_digest, policy_snapshot_id=policy_snapshot.id, registry_snapshot_id=registry_snapshot.id, requested_by=requested_by, requested_at=datetime.now(timezone.utc), started_at=datetime.now(timezone.utc), status=RunStatus.RUNNING.value, ) self.repository.save_check_run(run) stage_runs: List[ComplianceStageRun] = [] violations: List[ComplianceViolation] = [] report: Optional[ComplianceReport] = None context = ComplianceStageContext( run=run, candidate=candidate, manifest=manifest, policy=policy_snapshot, registry=registry_snapshot, ) try: for stage in self.stages: started = datetime.now(timezone.utc) result = stage.execute(context) finished = datetime.now(timezone.utc) stage_run = build_stage_run_record( run_id=run.id, stage_name=stage.stage_name, result=result, started_at=started, finished_at=finished, ) self._persist_stage_run(stage_run) stage_runs.append(stage_run) if result.violations: self._persist_violations(result.violations) violations.extend(result.violations) run.final_status = derive_final_status(stage_runs).value run.status = RunStatus.SUCCEEDED.value run.finished_at = datetime.now(timezone.utc) self.repository.save_check_run(run) report = self.report_builder.build_report_payload(run, violations) report = self.report_builder.persist_report(report) run.report_id = report.id self.repository.save_check_run(run) logger.reflect(f"[REFLECT] Compliance run completed run_id={run.id} final_status={run.final_status}") except Exception as exc: # noqa: BLE001 run.status = RunStatus.FAILED.value run.final_status = ComplianceDecision.ERROR.value run.failure_reason = str(exc) run.finished_at = datetime.now(timezone.utc) self.repository.save_check_run(run) logger.explore(f"[EXPLORE] Compliance run failed run_id={run.id}: {exc}") return ComplianceExecutionResult( run=run, report=report, stage_runs=stage_runs, violations=violations, ) # [/DEF:execute_run:Function] # [/DEF:ComplianceExecutionService:Class] # [/DEF:backend.src.services.clean_release.compliance_execution_service:Module]