Files
breakpilot-compliance/backend-compliance/tests/test_cookie_classification_gate.py
T
Benjamin Admin 869e7aeb1e fix(cookie): gate non-COOKIE_POLICY controls out of the cookie-policy scan
The cookie agent loaded 100 controls, 11 of which have no COOKIE_POLICY in
applicable_artifacts -- Security/TOM/Audit (PROCESS) or Banner-behaviour
(BEHAVIOR) controls that produce nonsense findings against a cookie policy
(e.g. "TOMs not documented"). Add a cookie classification gate (analogous to the
DSE gate, keyed on COOKIE_POLICY, without the needs_review carve-out since the
artifact signal is decisive and the set is inventory-verified). Controls are
routed out, not deleted. Effect vs Opus-GT: FP 16->11, FN 179->159; the
remaining FN=159 over-rescue is a separate (judge/criteria) question, not routing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-22 17:37:48 +02:00

43 lines
1.7 KiB
Python

"""Tests for the cookie-policy applicability gate: controls without a
COOKIE_POLICY artifact are routed out of the findings scan (not deleted),
and the gate is fail-safe (no DSN -> no filter)."""
import pytest
from compliance.services.specialist_agents.cookie_policy._classification_gate import (
apply_gate, load_cookie_gate,
)
def test_apply_gate_splits_kept_and_routed():
controls = [
{"control_id": "COOK-1", "title": "Kategorien"},
{"control_id": "TOM-1", "title": "Verschlüsselung"},
{"control_id": "BAN-1", "title": "Consent vor Setzen"},
]
gate = {
"TOM-1": {"obligation_type": "TECHNICAL", "check_intent": "DIRECT_TECHNICAL",
"applicable_artifacts": ["TOM", "AUDIT"]},
"BAN-1": {"obligation_type": "TECHNICAL", "check_intent": "DIRECT_TECHNICAL",
"applicable_artifacts": ["COOKIE_BANNER", "SYSTEMSCAN"]},
}
kept, routed = apply_gate(controls, gate)
assert [c["control_id"] for c in kept] == ["COOK-1"]
assert {c["control_id"] for c in routed} == {"TOM-1", "BAN-1"}
# routed entries carry title + classification metadata for downstream routing
tom = next(c for c in routed if c["control_id"] == "TOM-1")
assert tom["title"] == "Verschlüsselung"
assert tom["applicable_artifacts"] == ["TOM", "AUDIT"]
def test_apply_gate_empty_gate_keeps_all():
controls = [{"control_id": "A"}, {"control_id": "B"}]
kept, routed = apply_gate(controls, {})
assert len(kept) == 2 and routed == []
@pytest.mark.asyncio
async def test_load_cookie_gate_no_dsn_is_failsafe(monkeypatch):
monkeypatch.delenv("DATABASE_URL", raising=False)
monkeypatch.delenv("COMPLIANCE_DATABASE_URL", raising=False)
assert await load_cookie_gate("") == {}