diff --git a/rein_aharness/glas_execution.py b/rein_aharness/glas_execution.py index 926b7b2..6afe366 100644 --- a/rein_aharness/glas_execution.py +++ b/rein_aharness/glas_execution.py @@ -14,6 +14,7 @@ from typing import Any from rein_aharness.ops_run_client import OpsRun, OpsRunConfig, resolve_ops_target GLAS_APPROACH = "glas-profile" +GLAS_ACTOR = "agt" _SCALAR_REFS = ( "correlation_id", @@ -38,7 +39,10 @@ def _request_kwargs(run: OpsRun, config: OpsRunConfig, report_to_hub: bool) -> d "repo": str(resolve_ops_target(run, config)), "title": run.title or "(untitled)", "description": run.description or "", - "actor": config.worker_id, + # 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, diff --git a/tests/test_glas_execution.py b/tests/test_glas_execution.py index 3deec0a..76a5e78 100644 --- a/tests/test_glas_execution.py +++ b/tests/test_glas_execution.py @@ -7,7 +7,7 @@ from pathlib import Path import pytest -from rein_aharness.glas_execution import GlasExecutionError, execute_profiled_run +from rein_aharness.glas_execution import GLAS_ACTOR, GlasExecutionError, execute_profiled_run from rein_aharness.ops_run_client import OpsRun, OpsRunConfig @@ -69,7 +69,7 @@ def test_profiled_run_builds_complete_execution_request(tmp_path: Path) -> None: "repo": str(repo.resolve()), "title": "Governed task", "description": "Do the bounded work", - "actor": "rein-aharness@test", + "actor": GLAS_ACTOR, "project": "rein-aharness", "request_id": "run-1", "correlation_id": "corr-1", @@ -91,3 +91,39 @@ def test_profiled_run_rejects_invalid_gateway_result(tmp_path: Path) -> None: request_factory=lambda **kwargs: kwargs, gateway=lambda request: {"evidence": {}}, ) + + +def test_profiled_actor_validates_against_real_glas_and_sandboxer(tmp_path: Path) -> None: + contract = pytest.importorskip("glas_harness.contract") + sandbox_models = pytest.importorskip("sandboxer.models") + repo = _repo(tmp_path) + captured = {} + + def validating_gateway(request): + captured["request"] = request + captured["sandbox_request"] = sandbox_models.SandboxCreateRequest( + profile="profile.bwrap-local", + inputs={"repo": request.repo}, + consumer=sandbox_models.Consumer( + actor=request.actor, + project=request.project, + run_id=request.request_id, + ), + ) + return { + "ok": True, + "evidence": {"outcome": "succeeded"}, + "tool_output": "", + "tool_error": None, + } + + execute_profiled_run( + _run(repo), + OpsRunConfig(worker_id="rein-aharness@railiance01", repo_roots=(str(tmp_path),)), + request_factory=contract.ExecutionRequest, + gateway=validating_gateway, + ) + + assert captured["request"].actor == "agt" + assert captured["sandbox_request"].consumer.actor == sandbox_models.ActorType.AGT + assert captured["sandbox_request"].consumer.run_id == "run-1" diff --git a/workplans/REIN-A-0004-glas-profiled-ops-runs.md b/workplans/REIN-A-0004-glas-profiled-ops-runs.md index d432861..106adcc 100644 --- a/workplans/REIN-A-0004-glas-profiled-ops-runs.md +++ b/workplans/REIN-A-0004-glas-profiled-ops-runs.md @@ -4,12 +4,12 @@ type: workplan title: "Profile-driven ops-run execution through Glas" domain: infotech repo: rein-aharness -status: blocked +status: active owner: codex topic_slug: rein-aharness priority: high created: "2026-08-22" -updated: "2026-08-22" +updated: "2026-08-23" related: - ACTIVITY-WP-0032 - ACT-ADR-006 @@ -90,7 +90,7 @@ redaction-by-allowlist, bounding, and unusable bodies. ```task id: REIN-A-0004-T04 -status: wait +status: progress priority: high state_hub_task_id: "b19a4dab-d6d7-537a-8c8f-77217f0d9069" ``` @@ -124,3 +124,12 @@ backoff. Activity Core handoff `413a4041-cfb3-4d02-a41a-1d92b3de06af` contains the production traceback and requests migration application before a pilot is scheduled. T04 waits only on that upstream repair and the coordinated low-risk proof. + +**Resumed 2026-08-23:** Activity Core applied migration `0008` and the bounded +pilot reached the Glas branch with its selector and refs intact. It refused at +`sandbox_create` because `OpsRunConfig.worker_id` had been used as the Glas +actor, conflating queue lease identity (`rein-aharness@railiance01`) with the +governed actor type (`agt`). Activity Core handoff +`c9a4ae44-f092-424f-9a4d-9b4cf58d65fd` confirms a direct `actor=agt` +create/destroy preflight passed and requests the mapping correction plus real +Glas/sand-boxer model validation before the final pilot.