from __future__ import annotations import re from pydantic import BaseModel from typing import List DUAL_USE_PATTERNS = [ r"step-?by-?step", r"protocol", r"wet[- ]?lab", r"culture\s*conditions", r"viral\s*vector", r"pathogen", r"gain[- ]of[- ]function", r"increase\s*virulence", r"synthesis\s*of\s*toxin", r"biosafety\s*level\s*(2|3|4)", r"kill\s*curve", r"CFU|colony\s*forming\s*units", ] class SafetyDecision(BaseModel): allowed: bool rationale: str redactions: List[str] = [] class SafetyGuard: """Blocks operational/dual‑use outputs; allows high‑level literature review only.""" def gate(self, text: str) -> SafetyDecision: hits = [p for p in DUAL_USE_PATTERNS if re.search(p, text, flags=re.I)] if hits: return SafetyDecision( allowed=False, rationale="Operational/dual‑use intent detected. Only high‑level review permitted.", redactions=hits, ) return SafetyDecision(allowed=True, rationale="High‑level research intent.")