| 12345678910111213141516171819202122232425262728293031323334353637383940414243 |
- from __future__ import annotations
- from typing import Any
- from app.core.orchestration.models import PolicyDecision
- from app.core.orchestration.spec import (
- validate_schedule_plan,
- validate_workflow_spec,
- )
- ENVIRONMENTS = {"development", "test", "production"}
- def evaluate_candidate(
- workflow_spec: Any,
- schedule_plan: Any,
- *,
- environment: str,
- deploy_disabled: bool,
- canary_required: bool,
- ) -> PolicyDecision:
- workflow = validate_workflow_spec(workflow_spec)
- validate_schedule_plan(schedule_plan)
- if environment not in ENVIRONMENTS:
- raise ValueError("unsupported environment")
- has_write = any(
- node["type"] == "sql.execute" or node.get("purpose") == "write"
- for node in workflow["nodes"]
- )
- risk = "high" if has_write else ("medium" if environment == "production" else "low")
- reasons = []
- if environment == "production" and not deploy_disabled:
- reasons.append("production candidate must deploy disabled")
- if environment == "production" and has_write and not canary_required:
- reasons.append("production write candidate requires canary")
- return PolicyDecision(
- allowed=not reasons,
- risk=risk,
- reasons=tuple(reasons),
- )
|