fix: isolate rein results and normalize manager startup failures
Some checks failed
ci / validate (push) Has been cancelled

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
This commit is contained in:
tegwick 2026-09-06 01:13:23 +02:00
parent 73cee37ad8
commit 53f2abf7e0
8 changed files with 152 additions and 32 deletions

View file

@ -401,3 +401,17 @@ def test_teardown_failure_is_visible_in_evidence() -> None:
assert result.evidence.failure_stage == "teardown"
assert result.evidence.error == "teardown failed; inspect direct caller error"
assert result.tool_error == "cannot teardown"
def test_manager_initialization_failure_returns_redacted_evidence():
with patch("glas_harness.gateway.SandboxManager", side_effect=RuntimeError(
"private manager configuration"
)), patch("glas_harness.gateway.hub.post_progress_event") as post:
result = run_execution(_request(report_to_hub=True),
catalog=_catalog_with_readiness(), rein=_FakeRein())
assert not result.ok
assert result.evidence.failure_stage == "sandbox_create"
assert result.evidence.sandbox_id is None
assert result.tool_error == "private manager configuration"
assert "private manager configuration" not in str(post.call_args)
post.assert_called_once()

View file

@ -0,0 +1,36 @@
"""A reusable adapter must keep each sandbox's result in its own session."""
import json
from unittest.mock import MagicMock
import pytest
from glas_harness.contract import ToolCall
from glas_harness.reins.rein_aharness import ReinAharness
from glas_harness.reins.rein_openweights import ReinOpenWeights
from glas_harness.transport import ExecutionTransport
@pytest.mark.parametrize("adapter", [ReinAharness, ReinOpenWeights])
def test_interleaved_sessions_keep_their_own_outcomes_and_usage(adapter):
rein = adapter()
sessions = []
for index, ok in enumerate([True, False]):
transport = MagicMock(spec=ExecutionTransport)
transport.resolve_executable.return_value = "/runtime/rein"
transport.git_head.return_value = f"head-{index}"
transport.run.return_value = MagicMock(returncode=0 if ok else 1, stderr="",
stdout=json.dumps({"ok": ok, "tokens_spent": 10 + index,
"model": f"model-{index}", "reason": None if ok else "failed"}))
sessions.append({"transport": transport, "task_file": f"/workspace-{index}/task",
"timeout_seconds": 30, "head_before": "baseline"})
# Finish A only after B has reported its different result.
for session in sessions:
rein.dispatch_tool(session, ToolCall(name="run_task"))
first, second = [rein.end_session(session) for session in sessions]
assert first.outcome == "succeeded"
assert first.tokens_spent == 10
assert first.resolved_model == "model-0"
assert second.outcome == "failed"
assert second.tokens_spent == 11
assert second.resolved_model == "model-1"