fix(027): stabilize shared acceptance gates and compatibility collateral
This commit is contained in:
@@ -31,11 +31,12 @@ from ...models.clean_release import (
|
||||
ComplianceRun,
|
||||
ComplianceStageRun,
|
||||
ComplianceViolation,
|
||||
CheckFinalStatus,
|
||||
)
|
||||
from .policy_engine import CleanPolicyEngine
|
||||
from .repository import CleanReleaseRepository
|
||||
from .stages import derive_final_status
|
||||
from ...core.logger import belief_scope
|
||||
from ...core.logger import belief_scope, logger
|
||||
|
||||
|
||||
# [DEF:CleanComplianceOrchestrator:Class]
|
||||
@@ -54,28 +55,71 @@ class CleanComplianceOrchestrator:
|
||||
|
||||
# [DEF:start_check_run:Function]
|
||||
# @PURPOSE: Initiate a new compliance run session.
|
||||
# @PRE: candidate_id/policy_id/manifest_id identify existing records in repository.
|
||||
# @PRE: candidate_id and policy_id are provided; legacy callers may omit persisted manifest/policy records.
|
||||
# @POST: Returns initialized ComplianceRun in RUNNING state persisted in repository.
|
||||
# @SIDE_EFFECT: Reads manifest/policy and writes new ComplianceRun via repository.save_check_run.
|
||||
# @DATA_CONTRACT: Input -> (candidate_id:str, policy_id:str, requested_by:str, manifest_id:str), Output -> ComplianceRun
|
||||
def start_check_run(self, candidate_id: str, policy_id: str, requested_by: str, manifest_id: str) -> ComplianceRun:
|
||||
# @SIDE_EFFECT: Reads manifest/policy when present and writes new ComplianceRun via repository.save_check_run.
|
||||
# @DATA_CONTRACT: Input -> (candidate_id:str, policy_id:str, requested_by:str, manifest_id:str|None), Output -> ComplianceRun
|
||||
def start_check_run(
|
||||
self,
|
||||
candidate_id: str,
|
||||
policy_id: str,
|
||||
requested_by: str | None = None,
|
||||
manifest_id: str | None = None,
|
||||
**legacy_kwargs,
|
||||
) -> ComplianceRun:
|
||||
with belief_scope("start_check_run"):
|
||||
manifest = self.repository.get_manifest(manifest_id)
|
||||
actor = requested_by or legacy_kwargs.get("triggered_by") or "system"
|
||||
execution_mode = str(legacy_kwargs.get("execution_mode") or "").strip().lower()
|
||||
manifest_id_value = manifest_id
|
||||
|
||||
if manifest_id_value and str(manifest_id_value).strip().lower() in {"tui", "api", "scheduler"}:
|
||||
logger.reason(
|
||||
"Detected legacy positional execution_mode passed through manifest_id slot",
|
||||
extra={"candidate_id": candidate_id, "execution_mode": manifest_id_value},
|
||||
)
|
||||
execution_mode = str(manifest_id_value).strip().lower()
|
||||
manifest_id_value = None
|
||||
|
||||
manifest = self.repository.get_manifest(manifest_id_value) if manifest_id_value else None
|
||||
policy = self.repository.get_policy(policy_id)
|
||||
if not manifest or not policy:
|
||||
|
||||
if manifest_id_value and manifest is None:
|
||||
logger.explore(
|
||||
"Manifest lookup missed during run start; rejecting explicit manifest contract",
|
||||
extra={"candidate_id": candidate_id, "manifest_id": manifest_id_value},
|
||||
)
|
||||
raise ValueError("Manifest or Policy not found")
|
||||
|
||||
if policy is None:
|
||||
logger.explore(
|
||||
"Policy lookup missed during run start; using compatibility placeholder snapshot",
|
||||
extra={"candidate_id": candidate_id, "policy_id": policy_id, "execution_mode": execution_mode or "unspecified"},
|
||||
)
|
||||
|
||||
manifest_id_value = manifest_id_value or f"manifest-{candidate_id}"
|
||||
manifest_digest = getattr(manifest, "manifest_digest", "pending")
|
||||
registry_snapshot_id = (
|
||||
getattr(policy, "registry_snapshot_id", None)
|
||||
or getattr(policy, "internal_source_registry_ref", None)
|
||||
or "pending"
|
||||
)
|
||||
|
||||
check_run = ComplianceRun(
|
||||
id=f"check-{uuid4()}",
|
||||
candidate_id=candidate_id,
|
||||
manifest_id=manifest_id,
|
||||
manifest_digest=manifest.manifest_digest,
|
||||
manifest_id=manifest_id_value,
|
||||
manifest_digest=manifest_digest,
|
||||
policy_snapshot_id=policy_id,
|
||||
registry_snapshot_id=policy.registry_snapshot_id,
|
||||
requested_by=requested_by,
|
||||
registry_snapshot_id=registry_snapshot_id,
|
||||
requested_by=actor,
|
||||
requested_at=datetime.now(timezone.utc),
|
||||
started_at=datetime.now(timezone.utc),
|
||||
status=RunStatus.RUNNING,
|
||||
)
|
||||
logger.reflect(
|
||||
"Initialized compliance run with compatibility-safe dependency placeholders",
|
||||
extra={"run_id": check_run.id, "candidate_id": candidate_id, "policy_id": policy_id},
|
||||
)
|
||||
return self.repository.save_check_run(check_run)
|
||||
# [/DEF:start_check_run:Function]
|
||||
|
||||
@@ -88,33 +132,46 @@ class CleanComplianceOrchestrator:
|
||||
def execute_stages(self, check_run: ComplianceRun, forced_results: Optional[List[ComplianceStageRun]] = None) -> ComplianceRun:
|
||||
with belief_scope("execute_stages"):
|
||||
if forced_results is not None:
|
||||
# In a real scenario, we'd persist these stages.
|
||||
for index, result in enumerate(forced_results, start=1):
|
||||
if isinstance(result, ComplianceStageRun):
|
||||
stage_run = result
|
||||
else:
|
||||
status_value = getattr(result, "status", None)
|
||||
if status_value == "PASS":
|
||||
decision = ComplianceDecision.PASSED.value
|
||||
elif status_value == "FAIL":
|
||||
decision = ComplianceDecision.BLOCKED.value
|
||||
else:
|
||||
decision = ComplianceDecision.ERROR.value
|
||||
stage_run = ComplianceStageRun(
|
||||
id=f"{check_run.id}-stage-{index}",
|
||||
run_id=check_run.id,
|
||||
stage_name=result.stage.value,
|
||||
status=result.status.value,
|
||||
decision=decision,
|
||||
details_json={"details": result.details},
|
||||
)
|
||||
self.repository.stage_runs[stage_run.id] = stage_run
|
||||
|
||||
check_run.final_status = derive_final_status(forced_results).value
|
||||
check_run.status = RunStatus.SUCCEEDED
|
||||
return self.repository.save_check_run(check_run)
|
||||
|
||||
# Real Logic Integration
|
||||
candidate = self.repository.get_candidate(check_run.candidate_id)
|
||||
policy = self.repository.get_policy(check_run.policy_snapshot_id)
|
||||
if not candidate or not policy:
|
||||
check_run.status = RunStatus.FAILED
|
||||
return self.repository.save_check_run(check_run)
|
||||
|
||||
registry = self.repository.get_registry(check_run.registry_snapshot_id)
|
||||
manifest = self.repository.get_manifest(check_run.manifest_id)
|
||||
|
||||
if not registry or not manifest:
|
||||
if not candidate or not policy or not registry or not manifest:
|
||||
check_run.status = RunStatus.FAILED
|
||||
check_run.finished_at = datetime.now(timezone.utc)
|
||||
return self.repository.save_check_run(check_run)
|
||||
|
||||
# Simulate stage execution and violation detection
|
||||
# 1. DATA_PURITY
|
||||
summary = manifest.content_json.get("summary", {})
|
||||
purity_ok = summary.get("prohibited_detected_count", 0) == 0
|
||||
|
||||
if not purity_ok:
|
||||
check_run.final_status = ComplianceDecision.BLOCKED
|
||||
else:
|
||||
check_run.final_status = ComplianceDecision.PASSED
|
||||
|
||||
check_run.final_status = (
|
||||
ComplianceDecision.PASSED.value if purity_ok else ComplianceDecision.BLOCKED.value
|
||||
)
|
||||
check_run.status = RunStatus.SUCCEEDED
|
||||
check_run.finished_at = datetime.now(timezone.utc)
|
||||
|
||||
@@ -129,9 +186,18 @@ class CleanComplianceOrchestrator:
|
||||
# @DATA_CONTRACT: Input -> ComplianceRun, Output -> ComplianceRun
|
||||
def finalize_run(self, check_run: ComplianceRun) -> ComplianceRun:
|
||||
with belief_scope("finalize_run"):
|
||||
# If not already set by execute_stages
|
||||
if check_run.status == RunStatus.FAILED:
|
||||
check_run.finished_at = datetime.now(timezone.utc)
|
||||
return self.repository.save_check_run(check_run)
|
||||
|
||||
if not check_run.final_status:
|
||||
check_run.final_status = ComplianceDecision.PASSED
|
||||
stage_results = [
|
||||
stage_run
|
||||
for stage_run in self.repository.stage_runs.values()
|
||||
if stage_run.run_id == check_run.id
|
||||
]
|
||||
derived = derive_final_status(stage_results)
|
||||
check_run.final_status = derived.value
|
||||
|
||||
check_run.status = RunStatus.SUCCEEDED
|
||||
check_run.finished_at = datetime.now(timezone.utc)
|
||||
|
||||
Reference in New Issue
Block a user