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>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
"""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("") == {}
|
||||
Reference in New Issue
Block a user