Skip to content

Commit 9e951b3

Browse files
committed
test: add real CommitGate replay semantics tests
1 parent 812afd5 commit 9e951b3

1 file changed

Lines changed: 167 additions & 0 deletions

File tree

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
"""
2+
Real CommitGate replay semantics tests for enterprise-shaped ESP-001.
3+
4+
These tests call commit_gate_core.gate.CommitGate directly through the bridge.
5+
They remain synthetic and in-memory. They do not prove live runtime enforcement,
6+
production non-execution, enterprise readiness, or path-universal governance.
7+
"""
8+
9+
from __future__ import annotations
10+
11+
from datetime import datetime, timezone
12+
import importlib.util
13+
from pathlib import Path
14+
15+
16+
ROOT = Path(__file__).resolve().parents[1]
17+
ADAPTER_PATH = ROOT / "adapters" / "mock_email_adapter.py"
18+
BRIDGE_PATH = ROOT / "adapters" / "commit_gate_bridge.py"
19+
20+
adapter_spec = importlib.util.spec_from_file_location("mock_email_adapter", ADAPTER_PATH)
21+
mock_email_adapter = importlib.util.module_from_spec(adapter_spec)
22+
assert adapter_spec.loader is not None
23+
adapter_spec.loader.exec_module(mock_email_adapter)
24+
MockEmailAdapter = mock_email_adapter.MockEmailAdapter
25+
26+
bridge_spec = importlib.util.spec_from_file_location("commit_gate_bridge", BRIDGE_PATH)
27+
commit_gate_bridge = importlib.util.module_from_spec(bridge_spec)
28+
assert bridge_spec.loader is not None
29+
bridge_spec.loader.exec_module(commit_gate_bridge)
30+
31+
build_gate = commit_gate_bridge.build_gate
32+
esp001_attempt = commit_gate_bridge.esp001_attempt
33+
34+
35+
def valid_decision_record(*, nonce: str = "nonce-valid-001") -> dict[str, str]:
36+
attempt = esp001_attempt()
37+
return {
38+
"decision_id": "decision-esp-001-valid",
39+
"actor_id": attempt["actor_id"],
40+
"action": attempt["action"],
41+
"object_id": attempt["object_id"],
42+
"environment": attempt["environment"],
43+
"commit_hash": attempt["commit_hash"],
44+
"verdict": "ALLOW",
45+
"policy_version": "esp-v0.1",
46+
"issued_at": "2026-05-12T09:59:00Z",
47+
"expires_at": "2026-05-12T10:05:00Z",
48+
"nonce": nonce,
49+
"signature": "signed:test-signature",
50+
}
51+
52+
53+
def execute_with_record(adapter, record):
54+
attempt = esp001_attempt()
55+
56+
def mutation_callback(record_snapshot):
57+
adapter.send(
58+
recipient=attempt["object_id"],
59+
payload_hash=attempt["commit_hash"],
60+
actor=attempt["actor_id"],
61+
)
62+
63+
gate, audit = build_gate(mutation_callback=mutation_callback)
64+
result = gate.execute(
65+
record=record,
66+
actor_id=attempt["actor_id"],
67+
action=attempt["action"],
68+
object_id=attempt["object_id"],
69+
environment=attempt["environment"],
70+
commit_hash=attempt["commit_hash"],
71+
)
72+
return result, audit
73+
74+
75+
def test_real_commit_gate_allows_valid_record_and_calls_adapter_once() -> None:
76+
adapter = MockEmailAdapter()
77+
result, audit = execute_with_record(adapter, valid_decision_record())
78+
79+
assert result.allowed is True
80+
assert result.code == "ALLOW"
81+
assert adapter.send_call_count == 1
82+
assert len(adapter.sent_messages) == 1
83+
assert len(audit.events) == 1
84+
assert audit.events[0]["allowed"] is True
85+
assert audit.events[0]["code"] == "ALLOW"
86+
87+
88+
def test_real_commit_gate_replay_after_allow_denies_and_does_not_call_adapter_again() -> None:
89+
attempt = esp001_attempt()
90+
adapter = MockEmailAdapter()
91+
92+
def mutation_callback(record_snapshot):
93+
adapter.send(
94+
recipient=attempt["object_id"],
95+
payload_hash=attempt["commit_hash"],
96+
actor=attempt["actor_id"],
97+
)
98+
99+
gate, audit = build_gate(mutation_callback=mutation_callback)
100+
record = valid_decision_record(nonce="nonce-replay-allow-001")
101+
102+
first = gate.execute(
103+
record=record,
104+
actor_id=attempt["actor_id"],
105+
action=attempt["action"],
106+
object_id=attempt["object_id"],
107+
environment=attempt["environment"],
108+
commit_hash=attempt["commit_hash"],
109+
)
110+
replay = gate.execute(
111+
record=record,
112+
actor_id=attempt["actor_id"],
113+
action=attempt["action"],
114+
object_id=attempt["object_id"],
115+
environment=attempt["environment"],
116+
commit_hash=attempt["commit_hash"],
117+
)
118+
119+
assert first.allowed is True
120+
assert first.code == "ALLOW"
121+
assert replay.allowed is False
122+
assert replay.code == "DENY:NONCE_REPLAYED"
123+
assert adapter.send_call_count == 1
124+
assert len(adapter.sent_messages) == 1
125+
assert len(audit.events) == 2
126+
assert audit.events[0]["code"] == "ALLOW"
127+
assert audit.events[1]["code"] == "DENY:NONCE_REPLAYED"
128+
129+
130+
def test_real_commit_gate_missing_record_denial_is_stable_and_does_not_consume_nonce() -> None:
131+
attempt = esp001_attempt()
132+
adapter = MockEmailAdapter()
133+
134+
def mutation_callback(record_snapshot):
135+
adapter.send(
136+
recipient=attempt["object_id"],
137+
payload_hash=attempt["commit_hash"],
138+
actor=attempt["actor_id"],
139+
)
140+
141+
gate, audit = build_gate(mutation_callback=mutation_callback)
142+
143+
first = gate.execute(
144+
record=None,
145+
actor_id=attempt["actor_id"],
146+
action=attempt["action"],
147+
object_id=attempt["object_id"],
148+
environment=attempt["environment"],
149+
commit_hash=attempt["commit_hash"],
150+
)
151+
second = gate.execute(
152+
record=None,
153+
actor_id=attempt["actor_id"],
154+
action=attempt["action"],
155+
object_id=attempt["object_id"],
156+
environment=attempt["environment"],
157+
commit_hash=attempt["commit_hash"],
158+
)
159+
160+
assert first.allowed is False
161+
assert second.allowed is False
162+
assert first.code == "DENY:NO_DECISION_RECORD"
163+
assert second.code == "DENY:NO_DECISION_RECORD"
164+
assert adapter.send_call_count == 0
165+
assert adapter.sent_messages == []
166+
assert len(audit.events) == 2
167+
assert audit.events[0]["code"] == audit.events[1]["code"] == "DENY:NO_DECISION_RECORD"

0 commit comments

Comments
 (0)