feat(clean-release): complete compliance redesign phases and polish tasks T047-T052
This commit is contained in:
@@ -13,7 +13,7 @@ from dataclasses import dataclass
|
||||
from typing import Dict, Iterable, List, Tuple
|
||||
|
||||
from ...core.logger import belief_scope, logger
|
||||
from ...models.clean_release import CleanProfilePolicy, ResourceSourceRegistry
|
||||
from ...models.clean_release import CleanPolicySnapshot, SourceRegistrySnapshot
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -34,12 +34,12 @@ class SourceValidationResult:
|
||||
# @TEST_CONTRACT: CandidateEvaluationInput -> PolicyValidationResult|SourceValidationResult
|
||||
# @TEST_SCENARIO: policy_valid -> Enterprise clean policy with matching registry returns ok=True
|
||||
# @TEST_FIXTURE: policy_enterprise_clean -> file:backend/tests/fixtures/clean_release/fixtures_clean_release.json
|
||||
# @TEST_EDGE: missing_registry_ref -> policy has empty internal_source_registry_ref
|
||||
# @TEST_EDGE: missing_registry_ref -> policy has empty registry_snapshot_id
|
||||
# @TEST_EDGE: conflicting_registry -> policy registry ref does not match registry id
|
||||
# @TEST_EDGE: external_endpoint -> endpoint not present in enabled internal registry entries
|
||||
# @TEST_INVARIANT: deterministic_classification -> VERIFIED_BY: [policy_valid]
|
||||
class CleanPolicyEngine:
|
||||
def __init__(self, policy: CleanProfilePolicy, registry: ResourceSourceRegistry):
|
||||
def __init__(self, policy: CleanPolicySnapshot, registry: SourceRegistrySnapshot):
|
||||
self.policy = policy
|
||||
self.registry = registry
|
||||
|
||||
@@ -48,28 +48,39 @@ class CleanPolicyEngine:
|
||||
logger.reason("Validating enterprise-clean policy and internal registry consistency")
|
||||
reasons: List[str] = []
|
||||
|
||||
if not self.policy.active:
|
||||
reasons.append("Policy must be active")
|
||||
if not self.policy.internal_source_registry_ref.strip():
|
||||
reasons.append("Policy missing internal_source_registry_ref")
|
||||
if self.policy.profile.value == "enterprise-clean" and not self.policy.prohibited_artifact_categories:
|
||||
reasons.append("Enterprise policy requires prohibited artifact categories")
|
||||
if self.policy.profile.value == "enterprise-clean" and not self.policy.external_source_forbidden:
|
||||
reasons.append("Enterprise policy requires external_source_forbidden=true")
|
||||
if self.registry.registry_id != self.policy.internal_source_registry_ref:
|
||||
# Snapshots are immutable and assumed active if resolved by facade
|
||||
if not self.policy.registry_snapshot_id.strip():
|
||||
reasons.append("Policy missing registry_snapshot_id")
|
||||
|
||||
content = self.policy.content_json or {}
|
||||
profile = content.get("profile", "standard")
|
||||
|
||||
if profile == "enterprise-clean":
|
||||
if not content.get("prohibited_artifact_categories"):
|
||||
reasons.append("Enterprise policy requires prohibited artifact categories")
|
||||
if not content.get("external_source_forbidden"):
|
||||
reasons.append("Enterprise policy requires external_source_forbidden=true")
|
||||
|
||||
if self.registry.id != self.policy.registry_snapshot_id:
|
||||
reasons.append("Policy registry ref does not match provided registry")
|
||||
if not self.registry.entries:
|
||||
reasons.append("Registry must contain entries")
|
||||
|
||||
if not self.registry.allowed_hosts:
|
||||
reasons.append("Registry must contain allowed hosts")
|
||||
|
||||
logger.reflect(f"Policy validation completed. blocking_reasons={len(reasons)}")
|
||||
return PolicyValidationResult(ok=len(reasons) == 0, blocking_reasons=reasons)
|
||||
|
||||
def classify_artifact(self, artifact: Dict) -> str:
|
||||
category = (artifact.get("category") or "").strip()
|
||||
if category in self.policy.required_system_categories:
|
||||
content = self.policy.content_json or {}
|
||||
|
||||
required = content.get("required_system_categories", [])
|
||||
prohibited = content.get("prohibited_artifact_categories", [])
|
||||
|
||||
if category in required:
|
||||
logger.reason(f"Artifact category '{category}' classified as required-system")
|
||||
return "required-system"
|
||||
if category in self.policy.prohibited_artifact_categories:
|
||||
if category in prohibited:
|
||||
logger.reason(f"Artifact category '{category}' classified as excluded-prohibited")
|
||||
return "excluded-prohibited"
|
||||
logger.reflect(f"Artifact category '{category}' classified as allowed")
|
||||
@@ -89,7 +100,7 @@ class CleanPolicyEngine:
|
||||
},
|
||||
)
|
||||
|
||||
allowed_hosts = {entry.host for entry in self.registry.entries if entry.enabled}
|
||||
allowed_hosts = set(self.registry.allowed_hosts or [])
|
||||
normalized = endpoint.strip().lower()
|
||||
|
||||
if normalized in allowed_hosts:
|
||||
|
||||
Reference in New Issue
Block a user