Demo: sequence governance — individually-permitted steps, prohibited combination
EVE can block individually-permitted actions that combine into a prohibited sequence. This demo
allows read_pii and allows external_post on their own, but blocks external_post when it
follows read_pii in the same session (a read-then-exfiltrate chain).
Synthetic recording tools. No production credentials.
Readiness
- Action-sequence governance: PILOT_READY (part of the pilot-validated agent governance surface).
- Python only (
embedded(service)mode).
Setup
# demo_sequence_governance.py — synthetic fixtures only
from core.eve_sdk import EVE
IDENT = {"tenant_id": "acme", "principal_id": "agent-1", "session_id": "sess-1"}
reads, posts = [], []
def read_pii(**kwargs):
reads.append(kwargs); return {"records": ["synthetic-ssn-000-00-0000"]}
def external_post(**kwargs):
posts.append(kwargs); return {"status": "sent"}
# Forbidden ordering: external_post must not follow read_pii in the same session.
eve = EVE(policy="lending_v1", mode="embedded",
forbidden_sequences=[["read_pii", "external_post"]])
Code
# Baseline A: external_post alone is permitted.
solo = EVE(policy="lending_v1", mode="embedded",
forbidden_sequences=[["read_pii", "external_post"]])
a = solo.govern_tool_call(tool="external_post", arguments={"url": "https://sink.example"},
context={"tenant_id": "acme", "principal_id": "p2", "session_id": "s2"})
assert a.allowed, "external_post alone is permitted"
# Chain in ONE session: step 1 read_pii -> ALLOW.
s1 = eve.govern_tool_call(tool="read_pii", arguments={"subject": "cust-1"}, context=IDENT)
assert s1.allowed
if s1.allowed:
read_pii(subject="cust-1")
# Step 2 external_post AFTER read_pii -> BLOCK (prohibited sequence).
s2 = eve.govern_tool_call(tool="external_post",
arguments={"url": "https://sink.example"}, context=IDENT)
assert not s2.allowed, "external_post after read_pii must be blocked"
assert len(posts) == 0, "the exfiltration step must not execute"
print("sequence decision:", s2.action, s2.reason_codes)
Expected decision
| Step | Verdict | Tool executed |
|---|---|---|
external_post alone (fresh session) |
ALLOW | (not executed in demo) |
read_pii (chain step 1) |
ALLOW | yes (1 read recorded) |
external_post after read_pii (chain step 2) |
BLOCK (forbidden sequence) | no |
Expected evidence
{"action": "BLOCK",
"sequence": {"matched": ["read_pii", "external_post"], "step": 2},
"reason_codes": ["...forbidden_sequence..."],
"certificate": {"signature": "ed25519-...", "canon": "jcs-1"}}
Verification command
from core.eve_sdk import verify_evidence
assert verify_evidence("decision", s2.certificate, expected_tenant="acme")["valid"]
print("verify: True")
Zero-side-effect assertion
len(posts) == 0: the external_post step was blocked wherever it followed read_pii, so the
exfiltration side effect never ran. Only the permitted read_pii step executed.
Cleanup
reads.clear(); posts.clear()
No external state created.
Limitations
- Sequence state is per-session and in-process in the pilot; durable multi-instance sequence state is a deployment concern.
- PILOT_READY, not production. Enforcement depends on your code honoring the verdict (or a gateway/sidecar).