feat(runtime): consume governed Activity Core closes

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
This commit is contained in:
tegwick 2026-09-04 19:54:07 +02:00
parent 0e6d795aa4
commit d00ffcb402
22 changed files with 1218 additions and 148 deletions

View file

@ -36,6 +36,12 @@ def test_ops_run_from_api() -> None:
"correlation_id": "corr-1",
"goal_refs": ["goal:42@1"],
},
"repository_grant": {
"version": "1",
"allowed_paths": ["docs/", "README.md"],
"commit_count": {"min": 1, "max": 1},
"publish": False,
},
}
)
assert row.target_repo == "freedom-intelligence"
@ -45,6 +51,25 @@ def test_ops_run_from_api() -> None:
"correlation_id": "corr-1",
"goal_refs": ["goal:42@1"],
}
assert row.repository_grant is not None
assert row.repository_grant.grant_id == "af2e7c8275c9ba8c8f78485067f9608e"
def test_ops_run_from_api_refuses_invalid_repository_grant() -> None:
with pytest.raises(OpsRunError, match="invalid repository_grant") as exc_info:
OpsRun.from_api(
{
"id": "run-1",
"repository_grant": {
"version": "1",
"allowed_paths": ["../escape"],
"commit_count": {"min": 1, "max": 1},
"publish": False,
},
}
)
assert exc_info.value.code == "invalid_repository_grant"
def test_config_from_env(monkeypatch: pytest.MonkeyPatch) -> None:
@ -126,6 +151,38 @@ def test_complete_and_fail() -> None:
assert post.call_args.kwargs["json"]["reopen"] is True
def test_complete_parses_reconciliation_and_machine_error_code() -> None:
cfg = OpsRunConfig(base_url="http://example.test", worker_id="w")
client = ActivityCoreOpsClient(cfg)
accepted = MagicMock()
accepted.raise_for_status = MagicMock()
accepted.json.return_value = {
"id": "r1",
"activity_definition_id": "d",
"idempotency_key": "k",
"title": "t",
"description": "",
"state": "succeeded",
"labels": [],
"close_disposition": "reconciled",
}
with patch("rein_aharness.ops_run_client.httpx.post", return_value=accepted):
out = client.complete("r1", result={"ok": True})
assert out.close_disposition == "reconciled"
request = httpx.Request("POST", "http://example.test/ops-runs/r1/complete")
conflict = httpx.Response(
409,
request=request,
json={"detail": {"code": "terminal_conflict", "message": "conflict"}},
)
with patch("rein_aharness.ops_run_client.httpx.post", return_value=conflict):
with pytest.raises(OpsRunError) as exc_info:
client.complete("r1", result={"ok": True})
assert exc_info.value.status_code == 409
assert exc_info.value.code == "terminal_conflict"
def test_claim_http_error() -> None:
cfg = OpsRunConfig(base_url="http://example.test", worker_id="w")
client = ActivityCoreOpsClient(cfg)
@ -175,6 +232,30 @@ def test_ops_run_to_taskspec(tmp_path: Path) -> None:
assert spec.hub_task_id == "r1"
def test_ops_run_to_taskspec_carries_repository_grant(tmp_path: Path) -> None:
import subprocess
repo = tmp_path / "controlled"
repo.mkdir()
subprocess.run(["git", "init", "-q"], cwd=repo, check=True)
run = OpsRun.from_api(
{
"id": "r1",
"target_repo": "controlled",
"repository_grant": {
"version": "1",
"allowed_paths": ["docs/"],
"commit_count": {"min": 1, "max": 1},
"publish": False,
},
}
)
spec = ops_run_to_taskspec(run, OpsRunConfig(repo_roots=(str(tmp_path),)))
assert spec.repository_grant is run.repository_grant
def test_ops_run_to_taskspec_missing_repo() -> None:
run = OpsRun(
id="r1",