117 lines
4.8 KiB
Python
117 lines
4.8 KiB
Python
"""JSON serialization helpers for candidate API and CLI boundaries."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Mapping
|
|
|
|
from .models import ReleasePlan, ResourceBinding, RiskClass, TaskPlan, WorkflowStep
|
|
|
|
|
|
def task_plan_from_mapping(value: Mapping[str, Any]) -> TaskPlan:
|
|
binding_value = value["binding"]
|
|
binding = ResourceBinding(
|
|
repository=str(binding_value["repository"]),
|
|
branch=str(binding_value["branch"]),
|
|
base_oid=str(binding_value["base_oid"]),
|
|
allowed_paths=tuple(str(item) for item in binding_value.get("allowed_paths", ())),
|
|
)
|
|
steps = tuple(
|
|
WorkflowStep(
|
|
step_id=str(item["step_id"]),
|
|
worker_role=str(item["worker_role"]),
|
|
required_capabilities=tuple(str(cap) for cap in item.get("required_capabilities", ())),
|
|
depends_on=tuple(str(dep) for dep in item.get("depends_on", ())),
|
|
max_attempts=int(item.get("max_attempts", 1)),
|
|
timeout_seconds=int(item.get("timeout_seconds", 900)),
|
|
allowed_paths=tuple(str(path) for path in item.get("allowed_paths", ())),
|
|
)
|
|
for item in value.get("steps", ())
|
|
)
|
|
created_at_raw = value.get("created_at")
|
|
created_at = datetime.fromisoformat(created_at_raw) if created_at_raw else None
|
|
kwargs: dict[str, Any] = {
|
|
"task_id": str(value["task_id"]),
|
|
"intent": str(value["intent"]),
|
|
"binding": binding,
|
|
"risk": RiskClass(str(value.get("risk", RiskClass.MEDIUM.value))),
|
|
"steps": steps,
|
|
"evidence_requirements": tuple(str(item) for item in value.get("evidence_requirements", ())),
|
|
"production_side_effects_allowed": bool(value.get("production_side_effects_allowed", False)),
|
|
}
|
|
if created_at is not None:
|
|
kwargs["created_at"] = created_at
|
|
return TaskPlan(**kwargs)
|
|
|
|
|
|
def task_plan_to_mapping(plan: TaskPlan) -> dict[str, Any]:
|
|
return {
|
|
"task_id": plan.task_id,
|
|
"intent": plan.intent,
|
|
"binding": {
|
|
"repository": plan.binding.repository,
|
|
"branch": plan.binding.branch,
|
|
"base_oid": plan.binding.base_oid,
|
|
"allowed_paths": list(plan.binding.allowed_paths),
|
|
},
|
|
"risk": plan.risk.value,
|
|
"steps": [
|
|
{
|
|
"step_id": step.step_id,
|
|
"worker_role": step.worker_role,
|
|
"required_capabilities": list(step.required_capabilities),
|
|
"depends_on": list(step.depends_on),
|
|
"max_attempts": step.max_attempts,
|
|
"timeout_seconds": step.timeout_seconds,
|
|
"allowed_paths": list(step.allowed_paths),
|
|
}
|
|
for step in plan.steps
|
|
],
|
|
"evidence_requirements": list(plan.evidence_requirements),
|
|
"production_side_effects_allowed": plan.production_side_effects_allowed,
|
|
"created_at": plan.created_at.isoformat(),
|
|
"plan_digest": plan.digest(),
|
|
}
|
|
|
|
|
|
def release_plan_from_mapping(value: Mapping[str, Any]) -> ReleasePlan:
|
|
return ReleasePlan(
|
|
task_id=str(value["task_id"]),
|
|
repository=str(value["repository"]),
|
|
branch=str(value["branch"]),
|
|
version=str(value["version"]),
|
|
target_oid=str(value["target_oid"]),
|
|
tree_oid=str(value["tree_oid"]),
|
|
artifact_sha256=str(value["artifact_sha256"]),
|
|
manifest_sha256=str(value["manifest_sha256"]),
|
|
package_closure_sha256=str(value["package_closure_sha256"]),
|
|
evidence_closure_oid=str(value["evidence_closure_oid"]),
|
|
approval_plan_id=str(value["approval_plan_id"]),
|
|
rollback_approval_plan_id=str(value["rollback_approval_plan_id"]),
|
|
rollback_artifact_sha256=str(value["rollback_artifact_sha256"]),
|
|
expected_tag_oid=str(value["expected_tag_oid"]),
|
|
expected_target_oid=str(value["expected_target_oid"]),
|
|
production_config_sha256=str(value["production_config_sha256"]),
|
|
)
|
|
|
|
|
|
def release_plan_to_mapping(plan: ReleasePlan) -> dict[str, Any]:
|
|
return {
|
|
"task_id": plan.task_id,
|
|
"repository": plan.repository,
|
|
"branch": plan.branch,
|
|
"version": plan.version,
|
|
"target_oid": plan.target_oid,
|
|
"tree_oid": plan.tree_oid,
|
|
"artifact_sha256": plan.artifact_sha256,
|
|
"manifest_sha256": plan.manifest_sha256,
|
|
"package_closure_sha256": plan.package_closure_sha256,
|
|
"evidence_closure_oid": plan.evidence_closure_oid,
|
|
"approval_plan_id": plan.approval_plan_id,
|
|
"rollback_approval_plan_id": plan.rollback_approval_plan_id,
|
|
"rollback_artifact_sha256": plan.rollback_artifact_sha256,
|
|
"expected_tag_oid": plan.expected_tag_oid,
|
|
"expected_target_oid": plan.expected_target_oid,
|
|
"production_config_sha256": plan.production_config_sha256,
|
|
}
|