Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 7m5s
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
105 lines
4.5 KiB
Python
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)
|