citationEdge / tests /test_text_guard.py
omkarkudalkar222's picture
deploy: full CitationEdge update (text detection, report UI, fixes) for HF Spaces
497f49b
Raw
History Blame Contribute Delete
2.96 kB
"""Liability firewall: the rules that stop a false accusation."""
from text_detection import guard as tg
from text_detection.schema import DetectionResult, EnsembleResult, Verdict
def _enable_zeroshot_guard(monkeypatch):
monkeypatch.setattr(tg, "_ZEROSHOT_AI_OK", False)
def _mk_ensemble(verdict, p_fake, confidence):
return EnsembleResult(
verdict=verdict, p_fake=p_fake, confidence=confidence,
primary_evidence="x", detector_results=[],
)
def _mk_det(name, verdict, p_fake, confidence=0.9):
return DetectionResult(
detector=name, p_fake=p_fake, verdict=verdict, confidence=confidence,
)
def test_word_count_counts_words():
assert tg.word_count("hello world foo") == 3
assert tg.word_count("") == 0
def test_is_too_short_boundary_at_50():
assert tg.is_too_short(" ".join(["w"] * 49)) is True
assert tg.is_too_short(" ".join(["w"] * 50)) is False
def test_short_text_forced_uncertain_and_capped():
res = _mk_ensemble(Verdict.AI_GENERATED, 0.92, 0.90)
out = tg.apply_liability_firewall(res, "too short here", [])
assert out.verdict == Verdict.UNCERTAIN
assert out.confidence <= tg.SHORT_TEXT_CONF_CAP
# original untouched (immutability)
assert res.verdict == Verdict.AI_GENERATED
assert res.confidence == 0.90
def test_ai_verdict_withheld_when_only_zeroshot_agrees(monkeypatch):
_enable_zeroshot_guard(monkeypatch)
text = " ".join(["word"] * 80)
res = _mk_ensemble(Verdict.AI_GENERATED, 0.80, 0.60)
dets = [_mk_det("text_fastdetectgpt", Verdict.AI_GENERATED, 0.80)]
out = tg.apply_liability_firewall(res, text, dets)
assert out.verdict == Verdict.UNCERTAIN
def test_ai_verdict_kept_when_non_zeroshot_supports():
text = " ".join(["word"] * 80)
res = _mk_ensemble(Verdict.AI_GENERATED, 0.80, 0.60)
dets = [
_mk_det("text_fastdetectgpt", Verdict.AI_GENERATED, 0.80),
_mk_det("text_watermark", Verdict.AI_GENERATED, 0.98),
]
out = tg.apply_liability_firewall(res, text, dets)
assert out.verdict == Verdict.AI_GENERATED
def test_errored_zeroshot_vote_does_not_count_as_support(monkeypatch):
_enable_zeroshot_guard(monkeypatch)
text = " ".join(["word"] * 80)
res = _mk_ensemble(Verdict.AI_GENERATED, 0.80, 0.60)
dets = [
_mk_det("text_fastdetectgpt", Verdict.AI_GENERATED, 0.80),
DetectionResult(
detector="text_watermark", p_fake=0.9, verdict=Verdict.AI_GENERATED,
confidence=0.0, error="boom",
),
]
out = tg.apply_liability_firewall(res, text, dets)
assert out.verdict == Verdict.UNCERTAIN
def test_real_verdict_on_long_text_is_left_alone():
text = " ".join(["word"] * 80)
res = _mk_ensemble(Verdict.REAL, 0.10, 0.80)
dets = [_mk_det("text_fastdetectgpt", Verdict.REAL, 0.10)]
out = tg.apply_liability_firewall(res, text, dets)
assert out.verdict == Verdict.REAL
assert out.confidence == 0.80