feat: add gitea agentic runtime control plane
This commit is contained in:
49
engine/devops_agent/validator.py
Normal file
49
engine/devops_agent/validator.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from engine.devops_agent.spec import WorkflowSpec
|
||||
|
||||
WRITE_PERMISSIONS = {"issues", "pull_requests", "contents"}
|
||||
|
||||
|
||||
def _is_write_permission(value: Any) -> bool:
|
||||
return str(value).strip().lower() == "write"
|
||||
|
||||
|
||||
def validate_workflow_spec(spec: WorkflowSpec) -> list[str]:
|
||||
errors: list[str] = []
|
||||
|
||||
if spec.provider not in {"gitea"}:
|
||||
errors.append(f"unsupported provider: {spec.provider}")
|
||||
|
||||
triggers = spec.frontmatter.get("on")
|
||||
if not isinstance(triggers, dict) or not triggers:
|
||||
errors.append("workflow spec must declare at least one trigger in 'on'")
|
||||
|
||||
permissions = spec.frontmatter.get("permissions") or {}
|
||||
safe_outputs = spec.frontmatter.get("safe_outputs") or {}
|
||||
|
||||
if not isinstance(permissions, dict):
|
||||
errors.append("'permissions' must be a mapping")
|
||||
if not isinstance(safe_outputs, dict):
|
||||
errors.append("'safe_outputs' must be a mapping")
|
||||
if isinstance(permissions, dict):
|
||||
has_write_permission = any(
|
||||
permission_name in WRITE_PERMISSIONS and _is_write_permission(permission_value)
|
||||
for permission_name, permission_value in permissions.items()
|
||||
)
|
||||
if has_write_permission and not safe_outputs:
|
||||
errors.append("write permissions require declared safe_outputs")
|
||||
|
||||
policy = spec.frontmatter.get("policy") or {}
|
||||
if policy and not isinstance(policy, dict):
|
||||
errors.append("'policy' must be a mapping")
|
||||
elif isinstance(policy, dict) and "path_scope" in policy:
|
||||
path_scope = policy["path_scope"]
|
||||
if not isinstance(path_scope, list) or any(
|
||||
not isinstance(item, str) or not item.strip() for item in path_scope
|
||||
):
|
||||
errors.append("policy.path_scope must be a list of non-empty path prefixes")
|
||||
|
||||
return errors
|
||||
Reference in New Issue
Block a user