rein-aharness/tests/test_repository_artifact_bwrap.py
tegwick c63caf5568
Some checks are pending
Governed runtime contract / contract (push) Waiting to run
feat: import governed sandbox commits and enforce native CLI limits
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-09 14:08:10 +02:00

171 lines
6.2 KiB
Python

"""Opt-in real sandbox/Glas/worker proof; queue and task authoring are fixtures."""
from __future__ import annotations
import json
import os
from pathlib import Path
from unittest.mock import MagicMock
import pytest
from glas_harness.contract import (
ExecutionSummary,
OperationalReadiness,
Rein,
ToolResult,
)
from glas_harness.gateway import run_execution
from glas_harness.profiles import ProfileCatalog
from glas_harness.transport import transport_from_sandbox
from sandboxer.core.manager import SandboxManager
from sandboxer.lifecycle.store import SandboxStore
from rein_aharness.claim_loop import process_one
from rein_aharness.close_outbox import CloseOutbox
from rein_aharness.metrics import external_metrics_dir
from rein_aharness.ops_run_client import (
ActivityCoreOpsClient,
OpsRun,
OpsRunConfig,
OpsRunError,
)
from test_repository_artifact import commit, git
from rein_aharness.repository_grant import RepositoryGrant
pytestmark = pytest.mark.skipif(
os.environ.get("REIN_REAL_BWRAP") != "1", reason="opt-in kernel namespace proof"
)
class DeterministicRein(Rein):
calls = 0
workspace = None
head = None
def __init__(self, source, baseline):
self.source, self.baseline = source, baseline
def start_session(self, profile, inputs, sandbox):
transport = transport_from_sandbox(sandbox)
self.workspace = Path(transport.workspace)
return transport
def dispatch_tool(self, transport, tool_call):
self.calls += 1
code = """from pathlib import Path
import subprocess
Path('result.txt').write_text('sandbox-result-only\\n')
def git(*args):
p=subprocess.run(['git',*args],check=True,capture_output=True,text=True)
return p.stdout.strip()
git('add','result.txt')
git('-c','user.name=Fixture','-c','user.email=fixture@example.invalid','commit','-qm','bounded result')
print(git('rev-parse','HEAD'))
"""
result = transport.run(["python3", "-c", code], timeout=30)
assert result.returncode == 0, result.stderr
self.head = result.stdout.strip()
assert git(self.source, "rev-parse", "HEAD") == self.baseline
assert not (self.source / "result.txt").exists()
return ToolResult(ok=True, output="sandbox-result-only", tokens_spent=0)
def end_session(self, session):
return ExecutionSummary(
committed=True, commit_sha=self.head, outcome="succeeded", tokens_spent=0
)
def cleanup_session(self, session):
assert self.workspace.exists()
assert git(self.source, "rev-parse", "HEAD") == self.baseline
def test_real_bwrap_worker_import_and_close_replay(tmp_path, monkeypatch):
monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "data"))
monkeypatch.setenv("REIN_AHARNESS_STATE_DIR", str(tmp_path / "state"))
monkeypatch.setenv("SANDBOXER_NO_STATE_HUB", "1")
source = tmp_path / "source"
source.mkdir()
git(source, "init", "-q")
baseline = commit(source, "README.md", "baseline\n")
grant = RepositoryGrant.from_mapping(
{
"version": "1",
"allowed_paths": ["result.txt"],
"commit_count": {"min": 1, "max": 1},
"publish": False,
}
)
run = OpsRun(
id="fixture-run",
activity_definition_id="fixture-definition",
idempotency_key="fixture-key",
target_repo=str(source),
title="deterministic fixture",
description="no inference",
state="claimed",
harness_profile_ref="harness.agent-dev-local@1.0.0",
repository_grant=grant,
claim_owner="fixture-worker",
attempt=1,
)
client = MagicMock(spec=ActivityCoreOpsClient)
client.config = OpsRunConfig(
worker_id="fixture-worker", lease_seconds=90, repo_roots=(str(tmp_path),)
)
client.claim.return_value = [run]
client.heartbeat.return_value = run
client.complete.side_effect = [
OpsRunError("response lost", action="complete"),
OpsRun(
id=run.id,
activity_definition_id="fixture-definition",
idempotency_key="fixture-key",
target_repo=str(source),
title=run.title,
description=run.description,
state="succeeded",
close_disposition="reconciled",
),
]
catalog = ProfileCatalog()
profile, _ = catalog.resolve(run.harness_profile_ref)
catalog.profiles()[(profile.id, profile.version)] = profile.model_copy(
update={
"operational_readiness": OperationalReadiness(
status="ready",
reason="isolated test fixture",
owner="tests",
evidence_ref="test:artifact-bwrap",
)
}
)
manager = SandboxManager(store=SandboxStore(tmp_path / "sandboxes.json"))
rein = DeterministicRein(source, baseline)
monkeypatch.setattr(
"glas_harness.gateway.run_execution",
lambda request, **kwargs: run_execution(
request, catalog=catalog, rein=rein, manager=manager, **kwargs
),
)
outbox = CloseOutbox(state_dir=tmp_path / "state")
first = process_one(client, outbox=outbox, report_to_hub=False)
assert first.reason == "close evidence remains pending", first
assert not rein.workspace.exists()
assert git(source, "rev-parse", "HEAD") == rein.head
assert (source / "result.txt").read_text() == "sandbox-result-only\n"
assert not git(source, "status", "--porcelain")
assert outbox.status()["pending"] == 1
record = json.loads(
(external_metrics_dir(source, "rein-aharness") / "executions.jsonl")
.read_text()
.strip()
)
assert record["success"]
durable = json.dumps(client.complete.call_args.kwargs["result"])
assert rein.head in durable
assert "sandbox-result-only" not in durable and '"bundle"' not in durable
client.claim.return_value = []
second = process_one(client, outbox=outbox, report_to_hub=False)
assert second.empty and rein.calls == 1
assert client.complete.call_count == 2
assert client.heartbeat.call_count >= 1
assert git(source, "rev-list", "--count", "HEAD") == "2"
assert outbox.status() == {"pending": 0, "delivered": 1, "quarantined": 0}