"""The hidden tier is hidden only if the generator keeps it so. This is the gate. Two checks. The first is structural and exact: for every seed the free screen is byte-identical with the overlay on or off, for every overlay the screen can carry. The second is distributional: across seeds, the screen features a policy could key on do not separate hidden from benign beyond noise. The generator draws the tier BEFORE the template and the screen, so the two populations are the same draw; this test is what would catch a regression that made them differ. """ from __future__ import annotations import math import pytest from alert_triage.generator import canonical_json, compatible_overlays, generate, screen_of ALL = range(4096) @pytest.fixture(scope="module") def pairs(): out = [] for s in ALL: base = generate(s, overlay=None) if base["template"].startswith("S"): continue out.append((s, base)) return out def test_overlay_never_touches_the_screen(pairs) -> None: for seed, base in pairs: before = canonical_json(screen_of(base)) for kind in compatible_overlays(base): overlaid = generate(seed, overlay=kind) assert overlaid["label"] == "suspicious" and overlaid["overlay"] == kind assert canonical_json(screen_of(overlaid)) == before, (seed, kind) def test_the_seed_overlay_is_one_of_the_compatible_kinds(pairs) -> None: for seed, base in pairs: w = generate(seed) if w["overlay"]: assert w["overlay"] in compatible_overlays(base) def _features(w) -> list[float]: c = w["customer"] screen = screen_of(w) trig = screen["triggering_transactions"] amounts = [t["amount"] for t in trig] return [ float(c["prior_alerts"]), float(c["prior_sars"]), float(c["pep"]), float(sum(1 for cp in screen["screen_counterparties"] if cp["direction"] == "out")), float(sum(1 for a in amounts if a % 100000 == 0)) / max(1, len(amounts)), float(len(trig)), float(len({t["branch"] for t in trig if t["branch"]})), float(sum(r["wires_out"] > 0 for r in w["summary"])), float(screen["alert"]["rule"] == "R-STR-01"), float(c["expected_monthly_cash"] > 0), ] def test_screen_features_do_not_separate_hidden_from_benign() -> None: """Per-feature z-test between the two populations; nothing beyond 4 sigma.""" benign, hidden = [], [] for s in ALL: w = generate(s) if w["tier"] == "benign": benign.append(_features(w)) elif w["tier"] == "hidden": hidden.append(_features(w)) assert len(hidden) > 400 for j in range(len(benign[0])): b = [f[j] for f in benign] h = [f[j] for f in hidden] mb, mh = sum(b) / len(b), sum(h) / len(h) vb = sum((x - mb) ** 2 for x in b) / max(1, len(b) - 1) vh = sum((x - mh) ** 2 for x in h) / max(1, len(h) - 1) se = math.sqrt(vb / len(b) + vh / len(h)) or 1e-9 z = abs(mb - mh) / se assert z < 4.0, f"feature {j}: benign {mb:.3f} vs hidden {mh:.3f}, z={z:.1f}"