Spaces:
Runtime error
Runtime error
| """Post-generation output validator & abstention layer. | |
| Deterministic, pure-Python gate that runs AFTER extraction/generation and | |
| REJECTS any output that smuggles in non-evidence-grounded language: | |
| * forbidden hedging / synthesis phrases (``appears to``, ``likely``, ``overall``…), | |
| * fabricated metrics (percentages, confidence/authenticity/consistency scores), | |
| * unsupported severity escalation. | |
| A forbidden token only survives if it is present verbatim in the cited evidence | |
| (STEP: ABSOLUTE GROUNDING POLICY). The layer never rewrites text — it reports | |
| violations and the caller abstains (drops the record). No network, fully | |
| unit-testable. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from app.extraction.citation_validator import ( | |
| BANNED_SEVERITY_TERMS, | |
| normalize_for_match, | |
| ) | |
| # Hedging / synthesis / evaluation vocabulary that must never be introduced. | |
| FORBIDDEN_PHRASES: frozenset[str] = frozenset({ | |
| "appears to", "seems to", "likely", "suggests", "indicates", | |
| "approximately reliable", "overall", "authenticity", "consistency score", | |
| "confidence score", "reliability score", "assessment", "evaluation", | |
| "in summary", "in conclusion", "executive summary", "we recommend", | |
| "it is recommended", "concerning", "potentially hazardous", | |
| }) | |
| # Fabricated-metric patterns: percentages and explicit scoring statements. | |
| _PERCENT_RE = re.compile(r"\b\d{1,3}(?:\.\d+)?\s?%") | |
| _SCORE_RE = re.compile( | |
| r"\b(?:authenticity|reliability|consistency|confidence|quality)\s+" | |
| r"(?:score|rating|level|index)\b", | |
| re.IGNORECASE, | |
| ) | |
| def _present_in_evidence(term: str, evidence_norm: str) -> bool: | |
| return term in evidence_norm | |
| def find_violations(text: str, evidence: str = "") -> list[str]: | |
| """Return a list of violation descriptions for ``text``. | |
| A forbidden phrase / severity term is only a violation when it is NOT | |
| present verbatim in ``evidence``. Percentages and scoring statements are | |
| violations unless the identical token appears in evidence. | |
| """ | |
| if not text: | |
| return [] | |
| text_norm = normalize_for_match(text) | |
| evidence_norm = normalize_for_match(evidence or "") | |
| violations: list[str] = [] | |
| for phrase in FORBIDDEN_PHRASES: | |
| if phrase in text_norm and not _present_in_evidence(phrase, evidence_norm): | |
| violations.append(f"forbidden phrase {phrase!r}") | |
| for term in BANNED_SEVERITY_TERMS: | |
| if term in text_norm and not _present_in_evidence(term, evidence_norm): | |
| violations.append(f"unsupported severity term {term!r}") | |
| for m in _PERCENT_RE.findall(text): | |
| token = normalize_for_match(m) | |
| if token not in evidence_norm: | |
| violations.append(f"fabricated percentage {m.strip()!r}") | |
| for m in _SCORE_RE.findall(text): | |
| if normalize_for_match(m) not in evidence_norm: | |
| violations.append(f"fabricated metric {m.strip()!r}") | |
| return violations | |
| def is_clean(text: str, evidence: str = "") -> bool: | |
| """True when ``text`` introduces no forbidden/fabricated content.""" | |
| return not find_violations(text, evidence) | |
| def should_abstain( | |
| text: str, | |
| evidence: str = "", | |
| *, | |
| min_confidence: float = 1.0, | |
| confidence: float = 1.0, | |
| evidence_aligned: bool = True, | |
| source_attributed: bool = True, | |
| ) -> bool: | |
| """Abstention logic (STEP: ABSTENTION LOGIC). | |
| Returns True (drop the record / RETURN NOTHING) when any of: | |
| * confidence is below ``min_confidence``, | |
| * evidence alignment failed, | |
| * source attribution failed, | |
| * the text contains forbidden/fabricated content not grounded in evidence. | |
| """ | |
| if confidence < min_confidence: | |
| return True | |
| if not evidence_aligned: | |
| return True | |
| if not source_attributed: | |
| return True | |
| return not is_clean(text, evidence) | |