Classify evidence as load-bearing or attributive, draft the emission-cadence declaration for Taxonomy, treat silence as a stream finding, keep completeness separate from record richness, forbid immune memory as a state plane, and make containment proposals reconstructable to their origin. Observe real qonto-assistant audit events; deny-class completeness stays unknown until the source publishes a heartbeat. Assistant: grok Assistant-Session: 01a05ef1-9e5a-70f2-b0ff-0b05d6b38ae9
134 lines
5 KiB
Python
134 lines
5 KiB
Python
from kings_guard.cadence import load_qonto_assistant_cadence
|
|
from kings_guard.contracts import (
|
|
ReconciliationView,
|
|
SignalKind,
|
|
StreamCompleteness,
|
|
StreamHeartbeat,
|
|
)
|
|
from kings_guard.posture import PostureEvaluator, is_stream_finding
|
|
|
|
from helpers import load_pilot, observation_from_fixture
|
|
|
|
|
|
def test_cadence_draft_covers_both_forms_against_qonto() -> None:
|
|
cadence = load_qonto_assistant_cadence()
|
|
assert cadence.status == "taxonomy-draft"
|
|
assert cadence.owner == "Taxonomy"
|
|
assert cadence.drafter == "kings-guard"
|
|
assert cadence.source_system == "qonto-assistant"
|
|
assert cadence.reference_instance == "GH-WP-0002-T04"
|
|
assert cadence.forms() == {"expected-rate", "heartbeat-or-reconciliation"}
|
|
|
|
|
|
def test_unmet_declared_rate_is_a_stream_finding() -> None:
|
|
cadence = load_qonto_assistant_cadence()
|
|
stream = PostureEvaluator().evaluate_stream(
|
|
(),
|
|
cadence,
|
|
now="2026-07-24T09:10:00Z",
|
|
watching_since="2026-07-22T09:10:00Z",
|
|
heartbeats=(
|
|
StreamHeartbeat(
|
|
source_system="qonto-assistant",
|
|
timestamp="2026-07-24T09:00:00Z",
|
|
event_class="audit.heartbeat",
|
|
assertion="nothing-to-report",
|
|
counts={"audit.deny": 0},
|
|
),
|
|
),
|
|
reconciliation=ReconciliationView(source_counts={"audit.deny": 0}, evidence_counts={"audit.deny": 0}),
|
|
)
|
|
|
|
assert any(item.startswith("stream:cadence_unmet:audit.allow") for item in stream.findings)
|
|
assert all(is_stream_finding(item) for item in stream.findings)
|
|
assert stream.completeness is StreamCompleteness.DEGRADED
|
|
|
|
|
|
def test_missing_heartbeat_is_a_stream_finding() -> None:
|
|
fixture = load_pilot()
|
|
observation = observation_from_fixture(fixture)
|
|
cadence = load_qonto_assistant_cadence()
|
|
stream = PostureEvaluator().evaluate_stream(
|
|
(observation,),
|
|
cadence,
|
|
now="2026-07-24T10:10:00Z",
|
|
watching_since="2026-07-22T09:10:00Z",
|
|
heartbeats=(),
|
|
reconciliation=ReconciliationView(source_counts={"audit.deny": 1}, evidence_counts={"audit.deny": 1}),
|
|
)
|
|
|
|
assert any(item.startswith("stream:heartbeat_missing:audit.deny") for item in stream.findings)
|
|
assert "credential_exfil_probe" not in stream.findings
|
|
assert stream.completeness is StreamCompleteness.DEGRADED
|
|
|
|
|
|
def test_reconciliation_divergence_is_a_stream_finding() -> None:
|
|
fixture = load_pilot()
|
|
observation = observation_from_fixture(fixture)
|
|
cadence = load_qonto_assistant_cadence()
|
|
stream = PostureEvaluator().evaluate_stream(
|
|
(observation,),
|
|
cadence,
|
|
now="2026-07-23T10:10:00Z",
|
|
watching_since="2026-07-23T09:10:00Z",
|
|
heartbeats=(
|
|
StreamHeartbeat(
|
|
source_system="qonto-assistant",
|
|
timestamp="2026-07-23T10:00:00Z",
|
|
event_class="audit.heartbeat",
|
|
assertion="nothing-to-report",
|
|
counts={"audit.deny": 2},
|
|
),
|
|
),
|
|
reconciliation=ReconciliationView(
|
|
source_counts={"audit.deny": 2},
|
|
evidence_counts={"audit.deny": 1},
|
|
),
|
|
)
|
|
|
|
assert any(
|
|
item.startswith("stream:reconciliation_divergence:audit.deny") for item in stream.findings
|
|
)
|
|
assert stream.completeness is StreamCompleteness.DEGRADED
|
|
|
|
|
|
def test_stream_findings_are_distinguishable_from_content_findings() -> None:
|
|
fixture = load_pilot()
|
|
observation = observation_from_fixture(fixture)
|
|
cadence = load_qonto_assistant_cadence()
|
|
evaluation = PostureEvaluator().evaluate_with_stream(
|
|
fixture.genome,
|
|
observation,
|
|
cadence,
|
|
now="2026-07-24T10:10:00Z",
|
|
watching_since="2026-07-22T09:10:00Z",
|
|
heartbeats=(),
|
|
reconciliation=ReconciliationView(source_counts={"audit.deny": 1}, evidence_counts={"audit.deny": 1}),
|
|
)
|
|
|
|
content_findings = set(evaluation.assessment.findings)
|
|
stream_findings = set(evaluation.stream.findings if evaluation.stream else ())
|
|
assert "credential_exfil_probe" in content_findings
|
|
assert stream_findings
|
|
assert content_findings.isdisjoint(stream_findings)
|
|
assert all(is_stream_finding(item) for item in stream_findings)
|
|
kinds = {signal.signal_kind for signal in evaluation.signals}
|
|
assert SignalKind.POSTURE_HINT in kinds
|
|
assert SignalKind.STREAM_COMPLETENESS in kinds
|
|
|
|
|
|
def test_heartbeat_not_yet_due_does_not_false_alarm() -> None:
|
|
fixture = load_pilot()
|
|
observation = observation_from_fixture(fixture)
|
|
cadence = load_qonto_assistant_cadence()
|
|
stream = PostureEvaluator().evaluate_stream(
|
|
(observation,),
|
|
cadence,
|
|
now=observation.timestamp,
|
|
watching_since=observation.timestamp,
|
|
heartbeats=(),
|
|
reconciliation=ReconciliationView(source_counts={"audit.deny": 1}, evidence_counts={"audit.deny": 1}),
|
|
)
|
|
|
|
assert not any(item.startswith("stream:heartbeat_missing") for item in stream.findings)
|
|
assert stream.completeness is StreamCompleteness.UNKNOWN
|