Files
aios/active-runtime/app/aios_baseline/operations.py
T

259 lines
10 KiB
Python

"""Declarative, non-executing operation registry and timeout safety rules."""
from __future__ import annotations
from copy import deepcopy
from dataclasses import dataclass
from datetime import datetime, timezone
import math
import re
from typing import Any, Iterable, Mapping, Sequence
EFFECT_CLASSES = frozenset(
{"READ_ONLY", "IDEMPOTENT", "CONDITIONAL", "RECONCILABLE", "IRREVERSIBLE"}
)
_FORBIDDEN_EXECUTION_FIELDS = frozenset({"command", "shell", "argv", "executable", "script"})
_HANDLER_REF = re.compile(r"^[A-Za-z][A-Za-z0-9_.:-]{0,126}$")
def _invalid(code: str, field: str = "") -> ValueError:
return ValueError(f"{code}:{field}" if field else code)
def _text(value: object, field: str) -> str:
if not isinstance(value, str) or not value.strip():
raise _invalid("field_invalid", field)
return value.strip()
def _policy(value: object, field: str, allowed_modes: set[str]) -> dict[str, Any]:
if not isinstance(value, Mapping):
raise _invalid("policy_invalid", field)
result = deepcopy(dict(value))
mode = _text(result.get("mode"), f"{field}.mode").upper()
if mode not in allowed_modes:
raise _invalid("policy_mode_invalid", f"{field}.mode")
result["mode"] = mode
return result
@dataclass(frozen=True, slots=True)
class OperationDefinition:
operation_id: str
version: int | str
effect_class: str
handler_ref: str
input_schema: str | Mapping[str, Any]
required_permissions: tuple[str, ...]
timeout_seconds: float
readback: Mapping[str, Any]
retry: Mapping[str, Any]
reconcile: Mapping[str, Any]
rollback: Mapping[str, Any]
owner_boundary: Mapping[str, Any]
@classmethod
def from_dict(cls, data: Mapping[str, Any]) -> "OperationDefinition":
if not isinstance(data, Mapping):
raise _invalid("operation_definition_invalid")
forbidden = sorted(_FORBIDDEN_EXECUTION_FIELDS.intersection(data))
if forbidden:
raise _invalid("arbitrary_execution_forbidden", forbidden[0])
operation_id = _text(data.get("operation_id"), "operation_id")
version = data.get("version")
if (
isinstance(version, bool)
or not isinstance(version, (int, str))
or (isinstance(version, int) and version < 1)
or (isinstance(version, str) and not version.strip())
):
raise _invalid("field_invalid", "version")
effect_class = _text(data.get("effect_class"), "effect_class").upper()
if effect_class not in EFFECT_CLASSES:
raise _invalid("effect_class_invalid", "effect_class")
handler_ref = _text(data.get("handler_ref", data.get("handler")), "handler_ref")
if not _HANDLER_REF.fullmatch(handler_ref):
raise _invalid("handler_ref_invalid", "handler_ref")
input_schema = data.get("input_schema")
if not isinstance(input_schema, (str, Mapping)) or not input_schema:
raise _invalid("field_invalid", "input_schema")
input_schema = deepcopy(input_schema)
permissions = data.get("required_permissions", data.get("permissions"))
if not isinstance(permissions, Sequence) or isinstance(permissions, (str, bytes, bytearray)):
raise _invalid("field_invalid", "required_permissions")
required_permissions = tuple(
_text(permission, f"required_permissions[{index}]")
for index, permission in enumerate(permissions)
)
if len(set(required_permissions)) != len(required_permissions):
raise _invalid("duplicate_permission", "required_permissions")
timeout_seconds = data.get("timeout_seconds")
if (
isinstance(timeout_seconds, bool)
or not isinstance(timeout_seconds, (int, float))
or not math.isfinite(timeout_seconds)
or timeout_seconds <= 0
):
raise _invalid("field_invalid", "timeout_seconds")
readback = _policy(data.get("readback"), "readback", {"NONE", "STATE", "EXACT"})
if "required" in readback and not isinstance(readback["required"], bool):
raise _invalid("field_invalid", "readback.required")
retry = _policy(
data.get("retry"),
"retry",
{"NEVER", "SAFE", "AFTER_READBACK", "RECONCILE_FIRST"},
)
attempts = retry.get("max_attempts", 1)
if isinstance(attempts, bool) or not isinstance(attempts, int) or attempts < 1:
raise _invalid("field_invalid", "retry.max_attempts")
retry["max_attempts"] = attempts
reconcile = _policy(
data.get("reconcile"), "reconcile", {"NONE", "EXACT_READBACK", "CUSTOM", "REQUIRED"}
)
rollback = _policy(
data.get("rollback"), "rollback", {"NONE", "OPERATION", "COMPENSATE"}
)
if rollback["mode"] == "OPERATION":
_text(rollback.get("operation_id"), "rollback.operation_id")
owner_boundary = _policy(
data.get("owner_boundary"),
"owner_boundary",
{"NONE", "WITHIN_GRANT", "EXPLICIT_AUTHORIZATION", "CROSS_BOUNDARY_DENIED"},
)
restart_operation = (
"service.restart" in operation_id
or "service-restart" in operation_id
or handler_ref.endswith("service_restart")
)
if restart_operation and (
readback["mode"] != "EXACT"
or not readback.get("required", False)
or reconcile["mode"] == "NONE"
):
raise _invalid("service_restart_exact_readback_required")
return cls(
operation_id=operation_id,
version=version,
effect_class=effect_class,
handler_ref=handler_ref,
input_schema=input_schema,
required_permissions=required_permissions,
timeout_seconds=float(timeout_seconds),
readback=readback,
retry=retry,
reconcile=reconcile,
rollback=rollback,
owner_boundary=owner_boundary,
)
def timeout_action(self, outcome: str, attempts: int = 1) -> str:
return operation_timeout_action(self, outcome=outcome, attempts=attempts)
@property
def permissions(self) -> tuple[str, ...]:
return self.required_permissions
class OperationRegistry:
"""Lookup-only registry; it deliberately has no execute or shell interface."""
def __init__(self, definitions: Iterable[OperationDefinition | Mapping[str, Any]]) -> None:
self._definitions: dict[str, OperationDefinition] = {}
for raw in definitions:
definition = raw if isinstance(raw, OperationDefinition) else OperationDefinition.from_dict(raw)
if definition.operation_id in self._definitions:
raise _invalid("duplicate_operation_id", definition.operation_id)
self._definitions[definition.operation_id] = definition
def get(self, operation_id: str) -> OperationDefinition:
return self._definitions[_text(operation_id, "operation_id")]
@property
def definitions(self) -> tuple[OperationDefinition, ...]:
return tuple(self._definitions.values())
def operation_timeout_action(
definition: OperationDefinition,
outcome: str = "AMBIGUOUS",
attempts: int = 1,
) -> str:
"""Return ``RETRY``, ``RECONCILE`` or ``STOP`` after a timeout.
An unknown response from a mutating sink never authorizes a blind repeat.
Exact readback/reconciliation must first establish whether the effect happened.
"""
if not isinstance(definition, OperationDefinition):
raise _invalid("operation_definition_invalid")
normalized_outcome = _text(outcome, "outcome").upper()
if isinstance(attempts, bool) or not isinstance(attempts, int) or attempts < 1:
raise _invalid("field_invalid", "attempts")
if definition.effect_class == "IRREVERSIBLE":
return "STOP"
if definition.effect_class != "READ_ONLY" and normalized_outcome in {
"AMBIGUOUS",
"UNKNOWN",
"MAY_HAVE_SUCCEEDED",
}:
if definition.reconcile["mode"] != "NONE" or definition.readback.get("required", False):
return "RECONCILE"
return "STOP"
retry_mode = definition.retry["mode"]
if attempts >= definition.retry["max_attempts"] or retry_mode == "NEVER":
return "STOP"
if retry_mode in {"AFTER_READBACK", "RECONCILE_FIRST"} and normalized_outcome not in {
"NOT_OBSERVED",
"PROVEN_ABSENT",
}:
return "RECONCILE" if definition.reconcile["mode"] != "NONE" else "STOP"
return "RETRY"
def _timestamp(value: object) -> datetime | None:
if not isinstance(value, str):
return None
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError:
return None
if parsed.tzinfo is None or parsed.utcoffset() is None:
return None
return parsed.astimezone(timezone.utc)
def verify_service_restart(
before: Mapping[str, Any], after: Mapping[str, Any]
) -> dict[str, Any]:
"""Verify a restart with instance identity and start-time evidence.
Merely observing an active unit proves current activity, not that the requested
restart occurred.
"""
if not isinstance(before, Mapping) or not isinstance(after, Mapping):
return {"status": "UNKNOWN", "reasons": ["restart_observation_invalid"]}
if not isinstance(after.get("active"), bool):
return {"status": "UNKNOWN", "reasons": ["service_active_invalid"]}
if after["active"] is False:
return {"status": "DRIFT", "reasons": ["service_not_active"]}
before_id = before.get("instance_id")
after_id = after.get("instance_id")
before_started = _timestamp(before.get("started_at"))
after_started = _timestamp(after.get("started_at"))
if (
not isinstance(before_id, str)
or not before_id
or not isinstance(after_id, str)
or not after_id
or before_started is None
or after_started is None
):
return {"status": "UNKNOWN", "reasons": ["restart_identity_missing"]}
if before_id == after_id or after_started <= before_started:
return {"status": "DRIFT", "reasons": ["restart_not_observed"]}
return {"status": "VERIFIED", "reasons": []}