Files
breakpilot-compliance/backend-compliance/compliance/tests/test_dse_classification_gate.py
T
Benjamin_Boenisch 38a347a82a
CI / detect-changes (push) Successful in 7s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 9s
CI / validate-canonical-controls (push) Successful in 12s
CI / loc-budget (push) Successful in 24s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m11s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 24s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
feat(platform): live-wire AGB v2 + DSE v3 + Architektur-Tab (#29)
AGB v2 (decision_method routing, 71%FP->~0) + DSE v3 (4-layer, recovered from container) + Architektur-Tab into /sdk/agent live path. Incl CI robustness (detect-changes.sh + PR-head checkout) + security (hardcoded Qdrant key removed, gitleaks allowlist).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-21 12:58:26 +00:00

60 lines
2.0 KiB
Python

"""Tests fuer das DSE-Applicability-Gate (_classification_gate).
Deckt die reine Split-Logik (apply_gate) und das defensive Verhalten von
load_dse_gate ohne DB ab. Die DB-Abfrage selbst ist I/O und wird hier nicht
gegen eine echte DB getestet (defensiver Pfad: kein DSN -> leeres Dict)."""
import asyncio
import os
from compliance.services.specialist_agents.dse._classification_gate import (
apply_gate,
load_dse_gate,
)
def test_apply_gate_splits_findings_and_organizational():
controls = [
{"control_id": "AUTH-2051-A02", "title": "Speicherdauer nennen"},
{"control_id": "AUTH-2049-A01", "title": "VVT fuehren"},
]
gate = {
"AUTH-2049-A01": {
"obligation_type": "EVIDENCE",
"check_intent": "DIRECT_EVIDENCE",
"applicable_artifacts": ["VVT", "AUDIT"],
"reference_allowed": "NO",
}
}
kept, organizational = apply_gate(controls, gate)
assert [c["control_id"] for c in kept] == ["AUTH-2051-A02"]
assert len(organizational) == 1
org = organizational[0]
assert org["control_id"] == "AUTH-2049-A01"
assert org["title"] == "VVT fuehren"
assert org["applicable_artifacts"] == ["VVT", "AUDIT"]
assert org["check_intent"] == "DIRECT_EVIDENCE"
def test_apply_gate_empty_gate_keeps_all():
controls = [{"control_id": "X-1"}, {"control_id": "X-2"}]
kept, organizational = apply_gate(controls, {})
assert len(kept) == 2
assert organizational == []
def test_load_dse_gate_without_dsn_is_defensive():
"""Kein DSN + keine Env -> leeres Dict (kein Filter), kein Fehler."""
saved = (
os.environ.pop("DATABASE_URL", None),
os.environ.pop("COMPLIANCE_DATABASE_URL", None),
)
try:
result = asyncio.run(load_dse_gate(""))
assert result == {}
finally:
if saved[0] is not None:
os.environ["DATABASE_URL"] = saved[0]
if saved[1] is not None:
os.environ["COMPLIANCE_DATABASE_URL"] = saved[1]