Spaces:
Running
Running
| """ | |
| Assertion and Negation Triage for Regulatory Claims (NegEx-based heuristic engine). | |
| Distinguishes between Implemented, Planned, Absent, and Ambiguous controls. | |
| """ | |
| import re | |
| from typing import Tuple | |
| from src.core.models import AssertionStatus | |
| class AssertionTriage: | |
| def __init__(self): | |
| # Absent / Negated Patterns (Pre- and Post-modifiers) | |
| self.absent_patterns = [ | |
| r"\b(no|not|neither|nor|never|without)\b", | |
| r"\b(absent|absence|missing)\b", | |
| r"\b(lacks?|lacking|failed\s+to|omits?|omitted)\b", | |
| r"\b(not\s+yet|not\s+currently|not\s+implemented|not\s+conducted)\b", | |
| r"\b(no\s+fallback|no\s+oversight|no\s+mechanism|no\s+testing)\b", | |
| r"\b(untested|unmitigated|unmonitored)\b", | |
| r"\b(absence\s+of|exempt\s+from)\b", | |
| ] | |
| # Planned / Roadmap Patterns | |
| self.planned_patterns = [ | |
| r"\b(planned|planning|roadmap|scheduled|targeted|proposed)\b", | |
| r"\b(will\s+be|to\s+be\s+implemented|in\s+development|in\s+progress)\b", | |
| r"\b(future\s+(?:releases?|versions?|iterations?|work))\b", | |
| r"\b(under\s+(?:consideration|evaluation|review))\b", | |
| r"\b(might\s+be\s+considered|could\s+be\s+considered|considered\s+for)\b", | |
| r"\b(if\s+budget\s+permits|pending\s+approval)\b", | |
| r"\b(q[1-4]\s*202[0-9])\b", | |
| ] | |
| # Implemented / Verified Patterns | |
| self.implemented_patterns = [ | |
| r"\b(implemented|operational|deployed|enforced|verified)\b", | |
| r"\b(active|validated|integrated|established|maintained)\b", | |
| r"\b(tested\s+(?:and|with|via)|passed|certified|logged)\b", | |
| r"\b(in\s+production|monitored\s+24/7|real-time)\b", | |
| r"\b(equipped\s+with|provides\s+a\s+(?:manual|human|stop))\b", | |
| ] | |
| def analyze_assertion(self, text: str) -> Tuple[AssertionStatus, float, bool]: | |
| """ | |
| Analyzes the context sentence surrounding an extracted entity. | |
| Returns: | |
| - status (AssertionStatus): IMPLEMENTED, PLANNED, or ABSENT | |
| - confidence (float): 0.0 to 1.0 | |
| - requires_auditor_review (bool): True if ambiguous or borderline | |
| """ | |
| clean_text = text.lower().strip() | |
| absent_hits = sum(1 for p in self.absent_patterns if re.search(p, clean_text)) | |
| planned_hits = sum(1 for p in self.planned_patterns if re.search(p, clean_text)) | |
| implemented_hits = sum(1 for p in self.implemented_patterns if re.search(p, clean_text)) | |
| # Explicit negation takes precedence over generic auxiliary verbs (e.g. "deployed without oversight") | |
| if absent_hits > 0: | |
| if planned_hits > 0: | |
| # Contradiction between absent and planned (e.g., "currently absent but planned") | |
| return AssertionStatus.PLANNED, 0.65, True | |
| conf = min(0.96, 0.78 + (0.08 * absent_hits)) | |
| return AssertionStatus.ABSENT, conf, False | |
| if planned_hits > 0: | |
| conf = min(0.92, 0.75 + (0.08 * planned_hits)) | |
| return AssertionStatus.PLANNED, conf, False | |
| if implemented_hits > 0: | |
| confidence = min(0.96, 0.80 + (0.08 * implemented_hits)) | |
| return AssertionStatus.IMPLEMENTED, confidence, False | |
| # If no explicit cue found, default to IMPLEMENTED if affirmative sentence, | |
| # but mark as borderline for human confirmation | |
| return AssertionStatus.IMPLEMENTED, 0.58, True | |