activity-core/tests/test_glas_evidence.py
tegwick b63131e863 feat: reconcile granted ops run closes
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06bfe-2a55-7ed3-bacd-879977b099bf
2026-09-04 12:57:12 +02:00

174 lines
5.8 KiB
Python

"""Normalized Glas evidence boundary (ACTIVITY-WP-0032-T04)."""
from __future__ import annotations
import json
from activity_core.glas_evidence import (
normalise_execution_evidence,
normalise_ops_result,
normalise_repository_transaction,
)
def _gateway_result() -> dict:
return {
"ok": True,
"evidence": {
"request_id": "request-1",
"correlation_id": "corr-1",
"actor": "agt",
"project": "activity-core",
"target_repo": "activity-core",
"contract_version": "1.0",
"profile_ref": "harness.agent-dev@1.0.0",
"rein_id": "rein-aharness",
"rein_version": "0.1.0",
"model_route": "claude-code-cli",
"resolved_model": "claude-sonnet-4-6",
"sandbox_profile": "profile.bwrap-local",
"sandbox_id": "sandbox-1",
"tool_profile": "green-commit-only",
"outcome": "succeeded",
"started_at": "2026-08-22T20:00:00Z",
"finished_at": "2026-08-22T20:00:05Z",
"duration_s": 5.0,
"tokens_spent": 0,
"token_budget": 60000,
"commit_sha": "deadbeef",
"artifacts": ["README.md"],
"tool_events_count": 0,
"tool_events_completeness": "unavailable",
"refs": {
"assignment_ref": "assignment:42",
"goal_refs": ["goal:42@1", {"credential": "must-drop"}],
"api_key": "must-drop",
},
"raw_prompt": "must-drop",
"provider_response": {"must": "drop"},
},
"tool_output": "sensitive direct model output",
"tool_error": "sensitive provider exception",
"provider_blob": {"credential": "must-drop"},
}
def test_normalises_gateway_result_and_drops_direct_output() -> None:
result = normalise_ops_result(_gateway_result())
assert result["ok"] is True
evidence = result["execution_evidence"]
assert evidence["profile_ref"] == "harness.agent-dev@1.0.0"
assert evidence["rein_id"] == "rein-aharness"
assert evidence["tokens_spent"] == 0
assert evidence["tool_events_count"] == 0
assert evidence["tool_events_completeness"] == "unavailable"
assert evidence["refs"] == {
"assignment_ref": "assignment:42",
"goal_refs": ["goal:42@1"],
}
serialized = json.dumps(result)
for forbidden in (
"tool_output",
"tool_error",
"provider_blob",
"raw_prompt",
"provider_response",
"credential",
):
assert forbidden not in serialized
def test_rejects_invalid_enums_and_non_finite_measurements() -> None:
evidence = normalise_execution_evidence(
{
"outcome": "maybe",
"failure_stage": "provider-internal",
"duration_s": float("nan"),
"tokens_spent": -1,
"tool_events_completeness": "unknown-ish",
}
)
assert evidence == {}
def test_keeps_legacy_artifact_fields_but_not_unknown_blobs() -> None:
result = normalise_ops_result(
{
"ok": True,
"path": "briefs/report.md",
"head_after": "deadbeef",
"target_repo": "activity-core",
"artifact_urls": [
{"kind": "report", "label": "Report", "url": "https://example.test/a"},
{"kind": "unsafe", "label": "Unsafe", "url": "file:///tmp/key"},
],
"messages": [{"role": "user", "content": "secret"}],
}
)
assert result["path"] == "briefs/report.md"
assert result["artifact_urls"] == [
{"kind": "report", "label": "Report", "url": "https://example.test/a"}
]
assert "messages" not in result
def test_preserves_bounded_repository_transaction_identity() -> None:
transaction = normalise_repository_transaction(
{
"transaction_id": "tx-1",
"correlation_id": "run-1",
"baseline": {"repo_id": "repo-1", "head": "base", "secret": "drop"},
"repository_grant": {
"grant_id": "grant-1",
"acceptance_policy_id": "policy-1",
"version": "1",
"allowed_path_count": 2,
"allowed_paths_digest": "digest",
"min_commits": 1,
"max_commits": 1,
"publish": False,
"allowed_paths": ["must-not-persist"],
},
"acceptance": {
"policy_id": "policy-1",
"accepted": True,
"head": "result",
"commit_count": 1,
"commits": ["result"],
"changed_path_count": 1,
"changed_paths": ["docs/result.md"] * 101,
"changed_paths_digest": "paths-digest",
"clean_post_state": True,
"provider_blob": "drop",
},
"metrics": {
"storage": "external",
"session_id": "tx-1",
"projection_ready": True,
},
"tool_output": "drop",
}
)
assert transaction["transaction_id"] == "tx-1"
assert transaction["repository_grant"]["grant_id"] == "grant-1"
assert transaction["acceptance"]["accepted"] is True
assert len(transaction["acceptance"]["changed_paths"]) == 100
assert transaction["metrics"]["session_id"] == "tx-1"
assert "allowed_paths" not in transaction["repository_grant"]
assert "tool_output" not in transaction
assert "secret" not in transaction["baseline"]
def test_ops_result_accepts_repository_transaction_alias() -> None:
result = normalise_ops_result(
{"transaction": {"transaction_id": "tx-alias", "unknown": "drop"}}
)
assert result == {
"repository_transaction": {"transaction_id": "tx-alias"}
}