| """
|
| ERE gate adapter for the BERT entailment agent.
|
|
|
| Wraps every /verify response through the five-gate ERE protocol before
|
| the result is returned to the caller. A verdict that fails any gate is
|
| suppressed β the caller receives an ERE_HALT response instead.
|
|
|
| Gates (from sovereign-engine-v2/src/tools/ere.py):
|
| P1 -- No secrets in the output payload
|
| P2 -- No eval / code injection in the output
|
| P3 -- Loop safety
|
| P4 -- No telemetry beacons
|
| P5 -- SHA-256 audit seal (only if P1-P4 pass)
|
|
|
| The P5 seal is stored alongside the BLAKE3 attestation in the WORM ledger,
|
| giving each verified claim two independent cryptographic commitments:
|
| - BLAKE3 (daemon layer, over model + threshold + score + source)
|
| - SHA-256 ERE seal (gate layer, over agent_id + intent + verdict JSON)
|
| """
|
|
|
| from __future__ import annotations
|
| import json
|
| import sys
|
| import os
|
|
|
|
|
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
|
| from dataclasses import dataclass
|
|
|
|
|
| try:
|
|
|
| from src.tools.ere import EREGate, EREResult, ere_check
|
| except ImportError:
|
|
|
| from agent._ere_bundled import EREGate, EREResult, ere_check
|
|
|
|
|
| @dataclass
|
| class GatedVerdict:
|
| """Result returned by the ERE gate layer."""
|
| allowed: bool
|
| verdict: dict | None
|
| ere_seal: str | None
|
| gate_results: dict
|
| violations: list[str]
|
|
|
| def to_dict(self) -> dict:
|
| if self.allowed:
|
| return {
|
| **self.verdict,
|
| "ere_seal": self.ere_seal,
|
| "ere_gates": self.gate_results,
|
| }
|
| return {
|
| "allowed": False,
|
| "ere_halt": True,
|
| "violations": self.violations,
|
| "ere_gates": self.gate_results,
|
| }
|
|
|
|
|
| class BERTEREGate:
|
| """
|
| Wraps a raw BERT /verify response through the ERE five-gate protocol.
|
|
|
| Usage:
|
| gate = BERTEREGate()
|
| raw = {"score": 0.98, "verdict": "Entailment", "hash": "a3f8..."}
|
| gated = gate.check(
|
| premise="The Battle of Hastings took place in 1066.",
|
| hypothesis="Hastings occurred in 1066.",
|
| raw_verdict=raw,
|
| )
|
| if not gated.allowed:
|
| raise RuntimeError(f"ERE halt: {gated.violations}")
|
| return gated.to_dict()
|
| """
|
|
|
| def __init__(self) -> None:
|
| self._gate = EREGate()
|
|
|
| def check(
|
| self,
|
| premise: str,
|
| hypothesis: str,
|
| raw_verdict: dict,
|
| ) -> GatedVerdict:
|
| """
|
| Run ERE gates over the serialized verdict payload.
|
|
|
| The output that ERE inspects is the JSON-serialized verdict β any
|
| secrets, eval patterns, or telemetry injected by a compromised model
|
| or adversarial input would appear here.
|
| """
|
| output_str = json.dumps(raw_verdict, sort_keys=True)
|
| intent = f"entailment:{premise[:80]}|{hypothesis[:80]}"
|
|
|
| result: EREResult = self._gate.check(
|
| agent_id="bert-entailment-agent",
|
| intent=intent,
|
| output=output_str,
|
| )
|
|
|
| return GatedVerdict(
|
| allowed=result.passed,
|
| verdict=raw_verdict if result.passed else None,
|
| ere_seal=result.seal,
|
| gate_results=result.gates,
|
| violations=result.violations,
|
| )
|
|
|
|
|
|
|
|
|
| _default = BERTEREGate()
|
|
|
|
|
| def gate_verdict(premise: str, hypothesis: str, raw_verdict: dict) -> GatedVerdict:
|
| """Module-level convenience wrapper."""
|
| return _default.check(premise, hypothesis, raw_verdict)
|
|
|