case0 / scripts /net_audit.py
HusseinEid's picture
Case Zero - initial public release (fully local: Qwen2.5-1.5B via llama.cpp + Supertonic, custom pixel-noir SPA via gradio.Server)
414dc55
raw
history blame
2.95 kB
"""Off-grid proof: run a full playthrough with a socket guard and assert that no
non-loopback network connection is attempted.
python scripts/net_audit.py
Exits non-zero if any outbound connection is made. This backs the "Off the Grid"
claim: the served game (case load, interrogation, evidence, accusation, and the
on-device voice) reaches the network zero times.
"""
from __future__ import annotations
import contextlib
import os
import socket
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "src"))
# Mirror the deployed container: weights are baked in, analytics off, hub offline -
# any accidental download would surface as a violation rather than silently succeed.
os.environ.setdefault("HF_HUB_OFFLINE", "1")
os.environ.setdefault("TRANSFORMERS_OFFLINE", "1")
os.environ.setdefault("GRADIO_ANALYTICS_ENABLED", "False")
_violations: list[str] = []
_orig_connect = socket.socket.connect
def _is_loopback(host: str) -> bool:
return host in {"127.0.0.1", "::1", "localhost"} or host.startswith("127.")
def _guard(self, address): # type: ignore[no-untyped-def]
host = address[0] if isinstance(address, tuple) else str(address)
if not _is_loopback(str(host)):
_violations.append(str(host))
raise OSError(f"net_audit: blocked non-loopback connect to {host}")
return _orig_connect(self, address)
def main() -> int:
socket.socket.connect = _guard # type: ignore[method-assign]
from starlette.testclient import TestClient
from case_zero.api import build_server
client = TestClient(build_server())
# A full play loop over the golden case - load, interrogate, present the breaking
# exhibit, read a hint, then accuse - all server-authoritative, no network.
run = client.post("/api/case", json={"caseId": "GRAYMOOR-3107"}).json()["runId"]
client.post(f"/api/run/{run}/interrogate/iris", json={"questionId": "q3"})
client.post(f"/api/run/{run}/interrogate/iris", json={"presentEvidenceId": "keycard"})
client.get(f"/api/run/{run}/hint", params={"screen": "interro"})
client.post(
f"/api/run/{run}/accuse",
json={
"suspectId": "iris",
"motiveId": "m_credit",
"evidenceIds": ["keycard", "voicemail", "cctv"],
},
)
# Exercise the on-device voice path too (local Supertonic ONNX). Best-effort: a missing
# voice model is fine; a *network* attempt would already be recorded as a violation.
with contextlib.suppress(Exception):
client.post(f"/api/run/{run}/tts/iris", json={"text": "I was in the library all night."})
if _violations:
print(f"FAIL: {len(_violations)} outbound connection(s): {sorted(set(_violations))}")
return 1
print("PASS: full playthrough made zero non-loopback connections (Off the Grid verified).")
return 0
if __name__ == "__main__":
raise SystemExit(main())