kings-guard/tests/test_secrets_engine_snapshot.py
tegwick 31e9963933 Admit source evidence snapshots and harden stream completeness
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06e89-93a2-7aa2-82b3-ce5ccd2682e6
2026-09-05 00:42:19 +02:00

83 lines
3 KiB
Python

from copy import deepcopy
from dataclasses import asdict
import pytest
from kings_guard.adapters.secrets_engine import snapshot_from_engine
from kings_guard.contracts import StreamCompleteness
NOW = "2026-09-05T12:00:00Z"
PAYLOAD = {
"surface": "secret-use-evidence", "as_of": NOW, "completeness_claimed": False,
"cadence": {"form": "heartbeat", "interval": "1d"},
"lanes": [{"as_of": NOW, "catalog_id": "lane-1", "stage": "test", "kind": "kv"}],
}
BINDINGS = {"lane-1": ("tenant-1", "subject-1")}
def admit(payload, now=NOW, bindings=BINDINGS):
return snapshot_from_engine(payload, lane_bindings=bindings, now=now)
def test_catalog_only_snapshot_does_not_invent_evidence_or_completeness():
result = admit(PAYLOAD)
assert result.lanes[0].ready is None
assert result.lanes[0].revocation_succeeded is None
assert result.lanes[0].evidence_kind is None
assert result.completeness is StreamCompleteness.UNKNOWN
assert result.heartbeat_interval.total_seconds() == 86400
def test_evidence_preserves_false_and_drops_authorization_and_sensitive_fields():
payload = deepcopy(PAYLOAD)
payload["lanes"][0].update(ready=False, revocation_succeeded=False,
decision_id="dec-1", session_handle="session-1",
secret="never-retained", lifecycle_operation="revoke")
result = admit(payload)
assert result.lanes[0].ready is False
assert result.lanes[0].revocation_succeeded is False
assert result.lanes[0].lifecycle_operation == "revoke"
fields = asdict(result.lanes[0])
assert {"decision_id", "session_handle", "secret"}.isdisjoint(fields)
assert result.completeness is StreamCompleteness.UNKNOWN
@pytest.mark.parametrize(("now", "findings"), [
("2026-09-06T12:00:00Z", ()),
("2026-09-06T12:00:01Z", ("snapshot:stale",)),
("2026-09-05T11:59:59Z", ("snapshot:future_timestamp",)),
])
def test_freshness_does_not_upgrade_completeness(now, findings):
result = admit(PAYLOAD, now)
assert result.findings == findings
assert result.completeness is StreamCompleteness.UNKNOWN
def test_unbound_or_duplicate_lanes_cannot_cross_scope():
with pytest.raises(ValueError, match="unbound"):
admit(PAYLOAD, bindings={})
payload = deepcopy(PAYLOAD)
payload["lanes"].append(payload["lanes"][0])
with pytest.raises(ValueError, match="duplicate"):
admit(payload)
@pytest.mark.parametrize("change", [
{"completeness_claimed": True}, {"completeness_claimed": None},
{"cadence": {"form": "heartbeat", "interval": "0s"}},
{"surface": "authorization"}, {"lanes": None},
])
def test_invalid_envelope_is_rejected(change):
with pytest.raises(ValueError):
admit({**PAYLOAD, **change})
@pytest.mark.parametrize("change", [
{"ready": "false"}, {"revocation_attempted": 0},
{"as_of": "2026-09-04T12:00:00Z"}, {"evidence_kind": "guessed"},
])
def test_invalid_lane_is_rejected(change):
payload = deepcopy(PAYLOAD)
payload["lanes"][0].update(change)
with pytest.raises(ValueError):
admit(payload)