"""Profile-authoritative execution of activity-core ops runs through Glas. Glas and sand-boxer are sibling runtime packages rather than hard dependencies of rein-aharness's legacy paths. Imports therefore stay at the execution edge: profile-absent coexistence continues to work, while a profiled row fails closed with an actionable error if the governed runtime is not installed. """ from __future__ import annotations import math from collections.abc import Callable from typing import Any from rein_aharness.execution_cancel import ExecutionCancel, ExecutionCancelled, resolve_cancel from rein_aharness.ops_run_client import OpsRun, OpsRunConfig, resolve_ops_target GLAS_APPROACH = "glas-profile" GLAS_ACTOR = "agt" _SCALAR_REFS = ( "correlation_id", "assignment_ref", "role_ref", "duty_ref", ) _LIST_REFS = ("goal_refs", "resource_envelope_refs") _EVIDENCE_STRING_FIELDS = ( "request_id", "correlation_id", "actor", "project", "target_repo", "contract_version", "profile_ref", "rein_id", "rein_version", "model_route", "resolved_model", "sandbox_profile", "sandbox_id", "tool_profile", "outcome", "failure_stage", "error", "started_at", "finished_at", "commit_sha", "tool_events_completeness", ) _EVIDENCE_NUMBER_FIELDS = ( "duration_s", "tokens_spent", "token_budget", "tool_events_count", ) class GlasExecutionError(RuntimeError): """The authoritative Glas invocation could not produce a GatewayResult.""" def normalise_execution_evidence_for_close(raw: Any) -> dict[str, Any]: """Retain only bounded Glas evidence fields safe for durable close state.""" if not isinstance(raw, dict): return {} result: dict[str, Any] = {} for key in _EVIDENCE_STRING_FIELDS: value = raw.get(key) if isinstance(value, str): result[key] = value[:2000] if key == "error" else value[:500] for key in _EVIDENCE_NUMBER_FIELDS: value = raw.get(key) if ( isinstance(value, (int, float)) and not isinstance(value, bool) and math.isfinite(value) and value >= 0 ): result[key] = value artifacts = raw.get("artifacts") if isinstance(artifacts, list): result["artifacts"] = [ item[:1000] for item in artifacts[:20] if isinstance(item, str) and item ] refs: dict[str, Any] = {} raw_refs = raw.get("refs") if isinstance(raw_refs, dict): for key in _SCALAR_REFS: value = raw_refs.get(key) if isinstance(value, str) and value: refs[key] = value[:500] for key in _LIST_REFS: value = raw_refs.get(key) if isinstance(value, list): refs[key] = [ item[:500] for item in value[:50] if isinstance(item, str) and item ] if refs: result["refs"] = refs return result def _request_kwargs(run: OpsRun, config: OpsRunConfig, report_to_hub: bool) -> dict[str, Any]: if not run.harness_profile_ref: raise GlasExecutionError(f"ops_run {run.id} has no harness_profile_ref") refs = run.execution_refs kwargs: dict[str, Any] = { "harness_profile_ref": run.harness_profile_ref, "repo": str(resolve_ops_target(run, config)), "title": run.title or "(untitled)", "description": run.description or "", # Activity Core's worker_id owns the queue lease; it is not a Glas # actor type. Sand-boxer validates governed execution actors as # adm|agt|atm, so this runtime enters the gateway as an agent. "actor": GLAS_ACTOR, "project": "rein-aharness", "request_id": run.id, "report_to_hub": report_to_hub, } for key in _SCALAR_REFS: value = refs.get(key) if isinstance(value, str) and value: kwargs[key] = value for key in _LIST_REFS: value = refs.get(key) if isinstance(value, list): kwargs[key] = [item for item in value if isinstance(item, str)] return kwargs def execute_profiled_run( run: OpsRun, config: OpsRunConfig, *, report_to_hub: bool = True, request_factory: Callable[..., Any] | None = None, gateway: Callable[[Any], Any] | None = None, cancel: ExecutionCancel | None = None, ) -> dict[str, Any]: """Invoke Glas and return its complete JSON-compatible GatewayResult.""" guard = resolve_cancel(cancel) if guard is not None: guard.check() if request_factory is None or gateway is None: try: from glas_harness.contract import ExecutionRequest from glas_harness.gateway import run_execution except ImportError as exc: raise GlasExecutionError( "profiled ops_run requires glas-harness with sand-boxer support; " "install the sibling checkouts into the claim-worker environment" ) from exc request_factory = request_factory or ExecutionRequest gateway = gateway or run_execution try: request = request_factory(**_request_kwargs(run, config, report_to_hub)) result = gateway(request) raw = result.model_dump(mode="json") if hasattr(result, "model_dump") else result except ExecutionCancelled: raise except GlasExecutionError: raise except Exception as exc: if guard is not None and guard.cancelled: raise ExecutionCancelled(guard.reason or "cancelled") from None raise GlasExecutionError(f"Glas gateway invocation failed: {exc}") from exc if guard is not None: guard.check() if not isinstance(raw, dict) or not isinstance(raw.get("ok"), bool): raise GlasExecutionError("Glas gateway returned an invalid GatewayResult") if not isinstance(raw.get("evidence"), dict): raise GlasExecutionError("Glas GatewayResult is missing execution evidence") return raw