feat: add versioned execution profiles
This commit is contained in:
parent
641e85f5a8
commit
1cd890d871
34 changed files with 2087 additions and 471 deletions
|
|
@ -3,8 +3,18 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
from sandboxer.models import Reachability, SandboxState, SandboxStatus
|
||||
|
||||
from glas_harness.contract import Rein, SandboxHandle, ToolCall, ToolResult
|
||||
from glas_harness.gateway import run_task_through_rein
|
||||
from glas_harness.contract import (
|
||||
ExecutionRequest,
|
||||
ExecutionSummary,
|
||||
Rein,
|
||||
SandboxHandle,
|
||||
ToolCall,
|
||||
ToolResult,
|
||||
)
|
||||
from glas_harness.gateway import run_execution, run_task_through_rein
|
||||
|
||||
|
||||
PROFILE = "harness.agent-dev-local@1.0.0"
|
||||
|
||||
|
||||
class _FakeRein(Rein):
|
||||
|
|
@ -13,6 +23,7 @@ class _FakeRein(Rein):
|
|||
|
||||
def start_session(self, profile, inputs, sandbox: SandboxHandle):
|
||||
self.calls.append("start_session")
|
||||
assert str(profile.ref) == PROFILE
|
||||
assert sandbox.sandbox_id == "sbx1"
|
||||
assert sandbox.reachability.get("workspace_dir") == "/tmp/ws"
|
||||
return {"session": "s1"}
|
||||
|
|
@ -20,11 +31,24 @@ class _FakeRein(Rein):
|
|||
def dispatch_tool(self, session, tool_call: ToolCall) -> ToolResult:
|
||||
self.calls.append("dispatch_tool")
|
||||
assert tool_call.name == "run_task"
|
||||
return ToolResult(ok=True, output="done")
|
||||
return ToolResult(
|
||||
ok=True,
|
||||
output="sensitive direct output",
|
||||
events=[{"type": "tool_use"}],
|
||||
events_completeness="complete",
|
||||
tokens_spent=123,
|
||||
resolved_model="claude-sonnet-4-6",
|
||||
)
|
||||
|
||||
def end_session(self, session):
|
||||
self.calls.append("end_session")
|
||||
return {"commit_sha": "deadbeef", "committed": "True"}
|
||||
return ExecutionSummary(
|
||||
committed=True,
|
||||
commit_sha="deadbeef",
|
||||
outcome="succeeded",
|
||||
tokens_spent=123,
|
||||
resolved_model="claude-sonnet-4-6",
|
||||
)
|
||||
|
||||
|
||||
def _fake_status(sandbox_id: str = "sbx1") -> SandboxStatus:
|
||||
|
|
@ -42,29 +66,39 @@ def _fake_status(sandbox_id: str = "sbx1") -> SandboxStatus:
|
|||
)
|
||||
|
||||
|
||||
def test_run_task_through_rein_creates_and_destroys_sandbox() -> None:
|
||||
def _request(*, profile: str = PROFILE, report_to_hub: bool = False) -> ExecutionRequest:
|
||||
return ExecutionRequest(
|
||||
harness_profile_ref=profile,
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
request_id="req-1",
|
||||
correlation_id="corr-1",
|
||||
assignment_ref="assignment:42",
|
||||
report_to_hub=report_to_hub,
|
||||
)
|
||||
|
||||
|
||||
def test_run_execution_creates_and_destroys_sandbox() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
rein = _FakeRein()
|
||||
|
||||
result = run_task_through_rein(
|
||||
sandbox_profile="profile.bwrap-local",
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
rein=rein,
|
||||
manager=manager,
|
||||
report_to_hub=False,
|
||||
)
|
||||
result = run_execution(_request(), rein=rein, manager=manager)
|
||||
|
||||
assert rein.calls == ["start_session", "dispatch_tool", "end_session"]
|
||||
manager.create.assert_called_once()
|
||||
manager.destroy.assert_called_once_with("sbx1")
|
||||
assert result["tool_ok"] is True
|
||||
assert result["summary"]["committed"] == "True"
|
||||
assert result.ok is True
|
||||
assert result.evidence.profile_ref == PROFILE
|
||||
assert result.evidence.rein_id == "rein-aharness"
|
||||
assert result.evidence.commit_sha == "deadbeef"
|
||||
assert result.evidence.tokens_spent == 123
|
||||
assert result.evidence.refs["assignment_ref"] == "assignment:42"
|
||||
assert result.tool_output == "sensitive direct output"
|
||||
|
||||
|
||||
def test_run_task_through_rein_destroys_sandbox_even_on_failure() -> None:
|
||||
def test_run_execution_normalizes_execution_failure_and_tears_down() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
|
||||
|
|
@ -72,94 +106,89 @@ def test_run_task_through_rein_destroys_sandbox_even_on_failure() -> None:
|
|||
def dispatch_tool(self, session, tool_call):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
rein = _FailingRein()
|
||||
|
||||
try:
|
||||
run_task_through_rein(
|
||||
sandbox_profile="profile.bwrap-local",
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
rein=rein,
|
||||
manager=manager,
|
||||
report_to_hub=False,
|
||||
)
|
||||
except RuntimeError:
|
||||
pass
|
||||
result = run_execution(_request(), rein=_FailingRein(), manager=manager)
|
||||
|
||||
assert result.ok is False
|
||||
assert result.evidence.outcome == "failed"
|
||||
assert result.evidence.failure_stage == "execution"
|
||||
assert result.evidence.error == "execution failed; inspect direct caller error"
|
||||
assert result.tool_error == "boom"
|
||||
manager.destroy.assert_called_once_with("sbx1")
|
||||
|
||||
|
||||
def test_run_task_through_rein_reports_success_event() -> None:
|
||||
def test_run_execution_refuses_unknown_profile_before_sandbox() -> None:
|
||||
manager = MagicMock()
|
||||
|
||||
result = run_execution(_request(profile="harness.unknown@1.0.0"), manager=manager)
|
||||
|
||||
assert result.ok is False
|
||||
assert result.evidence.outcome == "refused"
|
||||
assert result.evidence.failure_stage == "resolution"
|
||||
assert "unknown harness profile" in (result.evidence.error or "")
|
||||
manager.create.assert_not_called()
|
||||
|
||||
|
||||
def test_hub_receives_normalized_evidence_without_raw_output() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
rein = _FakeRein()
|
||||
|
||||
with patch("glas_harness.gateway.hub.post_progress_event", return_value=True) as post:
|
||||
run_task_through_rein(
|
||||
sandbox_profile="profile.bwrap-local",
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
rein=rein,
|
||||
manager=manager,
|
||||
)
|
||||
result = run_execution(_request(report_to_hub=True), rein=_FakeRein(), manager=manager)
|
||||
|
||||
post.assert_called_once()
|
||||
kwargs = post.call_args.kwargs
|
||||
assert kwargs["event_type"] == "gateway_run"
|
||||
assert "ok)" in kwargs["summary"]
|
||||
assert kwargs["detail"]["ok"] is True
|
||||
assert kwargs["detail"]["sandbox_id"] == "sbx1"
|
||||
assert kwargs["detail"]["rein"] == "_FakeRein"
|
||||
detail = post.call_args.kwargs["detail"]
|
||||
assert detail["outcome"] == "succeeded"
|
||||
assert detail["profile_ref"] == PROFILE
|
||||
assert "tool_output" not in detail
|
||||
assert "sensitive direct output" not in str(detail)
|
||||
assert result.tool_output == "sensitive direct output"
|
||||
|
||||
|
||||
def test_run_task_through_rein_reports_failure_event_and_still_raises() -> None:
|
||||
def test_hub_failure_detail_excludes_raw_provider_error() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
|
||||
class _FailingRein(_FakeRein):
|
||||
def dispatch_tool(self, session, tool_call):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
rein = _FailingRein()
|
||||
raise RuntimeError("provider body containing sensitive material")
|
||||
|
||||
with patch("glas_harness.gateway.hub.post_progress_event", return_value=True) as post:
|
||||
try:
|
||||
run_task_through_rein(
|
||||
sandbox_profile="profile.bwrap-local",
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
rein=rein,
|
||||
manager=manager,
|
||||
)
|
||||
assert False, "expected RuntimeError to propagate"
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
post.assert_called_once()
|
||||
kwargs = post.call_args.kwargs
|
||||
assert "failed)" in kwargs["summary"]
|
||||
assert kwargs["detail"]["ok"] is False
|
||||
assert kwargs["detail"]["error"] == "boom"
|
||||
assert kwargs["detail"]["result"] is None
|
||||
|
||||
|
||||
def test_run_task_through_rein_skips_hub_when_disabled() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
rein = _FakeRein()
|
||||
|
||||
with patch("glas_harness.gateway.hub.post_progress_event") as post:
|
||||
run_task_through_rein(
|
||||
sandbox_profile="profile.bwrap-local",
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
rein=rein,
|
||||
manager=manager,
|
||||
report_to_hub=False,
|
||||
result = run_execution(
|
||||
_request(report_to_hub=True), rein=_FailingRein(), manager=manager
|
||||
)
|
||||
|
||||
post.assert_not_called()
|
||||
detail = post.call_args.kwargs["detail"]
|
||||
assert detail["error"] == "execution failed; inspect direct caller error"
|
||||
assert "sensitive material" not in str(detail)
|
||||
assert "sensitive material" in (result.tool_error or "")
|
||||
|
||||
|
||||
def test_wrapper_requires_and_reports_harness_profile() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
|
||||
result = run_task_through_rein(
|
||||
harness_profile=PROFILE,
|
||||
repo="/tmp/repo",
|
||||
title="t",
|
||||
description="d",
|
||||
rein=_FakeRein(),
|
||||
manager=manager,
|
||||
report_to_hub=False,
|
||||
)
|
||||
|
||||
assert result["ok"] is True
|
||||
assert result["evidence"]["profile_ref"] == PROFILE
|
||||
|
||||
|
||||
def test_teardown_failure_is_visible_in_evidence() -> None:
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
manager.destroy.side_effect = RuntimeError("cannot teardown")
|
||||
|
||||
result = run_execution(_request(), rein=_FakeRein(), manager=manager)
|
||||
|
||||
assert result.ok is False
|
||||
assert result.evidence.failure_stage == "teardown"
|
||||
assert result.evidence.error == "teardown failed; inspect direct caller error"
|
||||
assert result.tool_error == "cannot teardown"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue