test(s52): AST guard — socket calls confined to the _urllib_post seam

This commit is contained in:
Kjell Tore Guttormsen 2026-07-16 19:50:21 +02:00
commit fde44ceeb6

View file

@ -57,6 +57,52 @@ def test_webhook_gate_refuses_without_optin_and_posts_with_optin() -> None:
assert len(posts) == 1
# --- LOAD-BEARING: socket-opening CALLS confined to the _urllib_post seam -------------------------
def test_no_socket_call_outside_the_post_seam() -> None:
"""LOAD-BEARING (socket confinement): (a) ``notify.py`` never imports ``socket`` at all (no raw
sockets needed); (b) every CALL to ``urlopen`` / ``Request`` / ``socket.socket`` has
``_urllib_post`` as its nearest-enclosing function no other function opens a connection. The
module-level ``urllib`` IMPORT is ALLOWED (the single sanctioned import, exactly as
``ingest.py`` imports urllib at module scope) the guard scopes the forbidden thing to
socket-opening *calls*, not imports (AST, not substring the ``test_okf.py:216`` lesson).
Detach point: add a ``urlopen(...)`` call to any notifier body RED."""
tree = ast.parse((_SRC_DIR / "notify.py").read_text("utf-8"))
imported: set[str] = set()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
imported |= {a.name.split(".")[0] for a in node.names}
elif isinstance(node, ast.ImportFrom):
imported.add((node.module or "").split(".")[0])
assert "socket" not in imported, "notify.py must never import socket"
offending: list[str] = []
def visit(node: ast.AST, enclosing: str | None) -> None:
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
enclosing = node.name
if isinstance(node, ast.Call):
fn = node.func
name = (
fn.id
if isinstance(fn, ast.Name)
else fn.attr
if isinstance(fn, ast.Attribute)
else None
)
if name in {"urlopen", "Request", "socket"} and enclosing != "_urllib_post":
offending.append(f"{name} called in {enclosing or '<module>'}")
for child in ast.iter_child_nodes(node):
visit(child, enclosing)
visit(tree, None)
assert offending == [], (
f"socket-opening calls must live ONLY in _urllib_post, found: {offending}"
)
# --- LOAD-BEARING: transport failures never leak the secret-bearing URL ---------------------------