coulomb-social/tests/test_communication_gate.py
tegwick 789e69902d
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 7m5s
Harden original-date migration and verify Coulomb recovery admission
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
2026-10-27 23:51:27 +01:00

105 lines
4.5 KiB
Python

"""Prove the cross-owner gate cannot send, hide skips or leak inherited credentials."""
import importlib.util
import json
from pathlib import Path
import pytest
@pytest.fixture
def gate(tmp_path, monkeypatch):
script = Path(__file__).resolve().parents[1] / "scripts/check-communication.py"
spec = importlib.util.spec_from_file_location("communication_gate", script)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
contract = tmp_path / "contract.json"
contract.write_text(json.dumps({
"schema_version": 1, "owner": "synthetic-owner",
"test_file": "tests/test_contract.py", "required_tests": ["test_contract"],
"remaining_acceptance": ["User review remains separate"],
}))
monkeypatch.setattr(module, "CONTRACT", contract)
owner = tmp_path / "owner"
(owner / "src/email_connect").mkdir(parents=True)
(owner / "src/email_connect/__init__.py").write_text("")
(owner / "tests").mkdir()
return module, owner, tmp_path / "receipt.json"
def test_communication_gate_scrubs_credentials_and_does_not_modify_owner(gate, monkeypatch):
module, owner, receipt = gate
monkeypatch.setenv("SMTP_PASSWORD", "synthetic-inherited-secret")
test = owner / "tests/test_contract.py"
test.write_text(
"import os\ndef test_contract():\n assert 'SMTP_PASSWORD' not in os.environ\n"
)
before = sorted(p.relative_to(owner) for p in owner.rglob("*"))
evidence = module.check(owner, receipt)
assert evidence["passed"] and evidence["tests"] == 1
assert evidence["acceptance_complete"] is False
assert "synthetic-inherited-secret" not in receipt.read_text()
assert sorted(p.relative_to(owner) for p in owner.rglob("*")) == before
@pytest.mark.parametrize("body", [
("import socket\ndef test_contract():\n"
" socket.create_connection(('smtp.example.test', 25))\n"),
"import pytest\n@pytest.mark.skip\ndef test_contract():\n pass\n",
"def test_renamed():\n pass\n",
])
def test_communication_gate_refuses_network_disabled_or_missing_contract(gate, body):
module, owner, receipt = gate
(owner / "tests/test_contract.py").write_text(body)
evidence = module.check(owner, receipt)
assert evidence["passed"] is False
assert "smtp.example.test" not in receipt.read_text()
assert "RuntimeError" not in receipt.read_text()
def test_communication_gate_binds_each_required_function_to_its_module(gate):
module, owner, receipt = gate
module.CONTRACT.write_text(json.dumps({
"schema_version": 1, "owner": "synthetic-owner",
"test_files": ["tests/test_contract.py", "tests/test_other.py"],
"required_tests": ["test_contract::test_contract", "test_other::test_contract"],
"remaining_acceptance": [],
}))
(owner / "tests/test_contract.py").write_text("def test_contract():\n pass\n")
other = owner / "tests/test_other.py"
other.write_text("def test_other():\n pass\n")
evidence = module.check(owner, receipt)
assert not evidence["passed"]
assert evidence["missing_required_tests"] == ["test_other::test_contract"]
other.write_text("def test_contract():\n pass\n")
assert module.check(owner, receipt)["passed"]
def test_communication_gate_snapshots_and_hashes_explicit_recovery_helper(gate):
module, owner, receipt = gate
contract = json.loads(module.CONTRACT.read_text())
contract["helper_files"] = ["scripts/recovery.py"]
module.CONTRACT.write_text(json.dumps(contract))
(owner / "scripts").mkdir()
helper = owner / "scripts/recovery.py"
helper.write_text("PROOF = 'recovered'\n")
(owner / "tests/test_contract.py").write_text(
"import runpy\nfrom pathlib import Path\ndef test_contract():\n"
" helper = Path(__file__).parents[1] / 'scripts/recovery.py'\n"
" assert runpy.run_path(str(helper))['PROOF'] == 'recovered'\n"
)
evidence = module.check(owner, receipt)
assert evidence["passed"]
assert "scripts/recovery.py" in evidence["source_sha256"]
helper.write_text("PROOF = 'lost'\n")
assert not module.check(owner, receipt)["passed"]
@pytest.mark.parametrize("name", ["../recovery.py", "scripts/../../recovery.py", "scripts/key.env"])
def test_communication_gate_refuses_helpers_outside_python_allowlist(gate, name):
module, owner, receipt = gate
contract = json.loads(module.CONTRACT.read_text())
contract["helper_files"] = [name]
module.CONTRACT.write_text(json.dumps(contract))
with pytest.raises(ValueError, match="explicit Python files"):
module.check(owner, receipt)