feat(audit): publish sequenced heartbeat and reconciliation evidence

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ec5-7e2b-7743-ac08-719e1b0f42e2
This commit is contained in:
tegwick 2026-09-05 01:39:48 +02:00
parent fce60099c4
commit b9349782f4
32 changed files with 839 additions and 111 deletions

View file

@ -14,7 +14,9 @@ from qonto_assistant.security_watch import (
)
from qonto_assistant.service import CapabilityService
POLICY_FILE = Path(__file__).resolve().parents[1] / "src" / "qonto_assistant" / "policy" / "qonto-v1.yaml"
POLICY_FILE = (
Path(__file__).resolve().parents[1] / "src" / "qonto_assistant" / "policy" / "qonto-v1.yaml"
)
FIXTURE_DIR = Path(__file__).resolve().parent / "fixtures" / "qonto"
@ -53,7 +55,9 @@ def _service(tracker: DenyEscalationTracker, events: list[dict[str, object]]) ->
def test_tracker_allows_denies_below_threshold() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=3, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=3, window_seconds=60, lockout_seconds=300, clock=clock
)
tracker.record_deny("binky:prober", "arg_constraint")
tracker.record_deny("binky:prober", "arg_constraint")
@ -63,7 +67,9 @@ def test_tracker_allows_denies_below_threshold() -> None:
def test_tracker_locks_out_after_threshold_within_window() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=3, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=3, window_seconds=60, lockout_seconds=300, clock=clock
)
for _ in range(3):
tracker.record_deny("binky:prober", "arg_constraint")
@ -74,7 +80,9 @@ def test_tracker_locks_out_after_threshold_within_window() -> None:
def test_tracker_ignores_non_escalating_deny_reasons() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=3, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=3, window_seconds=60, lockout_seconds=300, clock=clock
)
for _ in range(10):
tracker.record_deny("binky:prober", "tenant_scope")
@ -85,7 +93,9 @@ def test_tracker_ignores_non_escalating_deny_reasons() -> None:
def test_tracker_denies_outside_window_do_not_accumulate() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=3, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=3, window_seconds=60, lockout_seconds=300, clock=clock
)
tracker.record_deny("binky:prober", "arg_constraint")
clock.advance(61)
@ -98,7 +108,9 @@ def test_tracker_denies_outside_window_do_not_accumulate() -> None:
def test_tracker_lockout_expires_after_lockout_window() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=3, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=3, window_seconds=60, lockout_seconds=300, clock=clock
)
for _ in range(3):
tracker.record_deny("binky:prober", "arg_constraint")
@ -118,7 +130,9 @@ def test_tracker_lockout_expires_after_lockout_window() -> None:
def test_tracker_is_scoped_per_actor() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=3, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=3, window_seconds=60, lockout_seconds=300, clock=clock
)
for _ in range(3):
tracker.record_deny("binky:prober", "arg_constraint")
@ -131,7 +145,9 @@ def test_tracker_is_scoped_per_actor() -> None:
def test_service_locks_out_actor_after_repeated_arg_constraint_denies() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=2, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=2, window_seconds=60, lockout_seconds=300, clock=clock
)
events: list[dict[str, object]] = []
service = _service(tracker, events)
@ -164,7 +180,9 @@ def test_service_locks_out_actor_after_repeated_arg_constraint_denies() -> None:
def test_service_does_not_lock_out_for_ordinary_denies() -> None:
clock = _FakeClock()
tracker = DenyEscalationTracker(threshold=2, window_seconds=60, lockout_seconds=300, clock=clock)
tracker = DenyEscalationTracker(
threshold=2, window_seconds=60, lockout_seconds=300, clock=clock
)
events: list[dict[str, object]] = []
service = _service(tracker, events)