kings-guard/tests/test_live_qonto_observation.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

67 lines
2.7 KiB
Python

from __future__ import annotations
import pytest
from helpers import load_pilot, observation_from_fixture
from kings_guard.cadence import load_qonto_assistant_source_cadence
from kings_guard.contracts import StreamCompleteness
from kings_guard.live import capture_qonto_assistant_events, qonto_assistant_available
from kings_guard.posture import PostureEvaluator
pytestmark = pytest.mark.skipif(
not qonto_assistant_available(),
reason="qonto-assistant checkout is required for live observation",
)
def test_fixture_regression_case_is_retained() -> None:
observation = observation_from_fixture()
assert observation.observation_id == "req-qonto-deny-credential-exfil"
assert observation.deny_reason == "credential_exfil"
def test_real_emitted_qonto_events_reach_the_evaluator() -> None:
fixture = load_pilot()
capture = capture_qonto_assistant_events(fixture.genome)
assert len(capture.events) >= 2
decisions = {event["decision"] for event in capture.events}
assert "allow" in decisions
assert "deny" in decisions
assert capture.mapping_notes
assert capture.stream_notes
assert all(
observation.source_system == "qonto-assistant" for observation in capture.observations
)
deny = next(item for item in capture.observations if item.decision.value == "deny")
evaluation = PostureEvaluator().evaluate(fixture.genome, deny)
assert evaluation.assessment.posture.value in {"elevated", "inflamed"}
assert evaluation.signals
for signal in evaluation.signals:
for request in signal.effector_requests:
assert request.authority_boundary in {"advisory_only", "metadata_only"}
# The source now emits identity binding and egress directly. The adapter must
# preserve those values instead of masking them with its legacy mapping hints.
for event, observation in zip(capture.events, capture.observations, strict=True):
assert observation.identity_binding == event["identity_binding"]
assert observation.egress_destination == event["egress_destination"]
assert capture.corrections_for_source == ()
assert capture.stream_corrections == ()
cadence = load_qonto_assistant_source_cadence()
stream_evaluation = PostureEvaluator().evaluate_with_stream(
fixture.genome,
deny,
cadence,
now=capture.heartbeats[-1].timestamp,
watching_since=capture.heartbeats[0].timestamp,
observations=capture.observations,
heartbeats=capture.heartbeats,
reconciliation=capture.reconciliation,
)
assert stream_evaluation.assessment.stream_completeness is StreamCompleteness.COMPLETE
assert stream_evaluation.stream is not None
assert stream_evaluation.stream.findings == ()