Demo: human approval, and rejecting a mutation after approval
An action can require human approval before it executes. EVE binds the approved request to the executed request: if the arguments are mutated between approval and execution, the mutated request is rejected before the side effect. This demo approves a request, then shows that a changed request no longer matches the approval.
Synthetic fixtures only. No production credentials.
Readiness
- Approval + approved-vs-executed binding: PILOT_READY (pilot-validated core governance architecture; MCP execution binding).
- Python SDK
eve-coreguard0.2.2 — release-candidate core client, pilot/private install. - Runs against the in-process embedded governance facade shipped with the EVE service.
Setup
# demo_human_approval.py — synthetic fixtures only
from core.eve_sdk import EVE
IDENT = {"tenant_id": "acme", "principal_id": "agent-1", "session_id": "sess-1"}
transfers = [] # recording target
def wire_transfer(**kwargs):
"""Synthetic recording tool. Records; no real payment."""
transfers.append(kwargs)
return {"transfer_id": "T-42", "status": "sent"}
eve = EVE(policy="lending_v1", mode="embedded")
Code
# 1) An action that requires approval is proposed. The verdict withholds execution.
proposed = eve.govern_tool_call(
tool="wire_transfer",
arguments={"amount": 100000, "to": "vendor-A"},
context={**IDENT, "requires_approval": True},
)
assert not proposed.allowed, "must not auto-execute; awaiting approval"
assert len(transfers) == 0
# 2) A human approves the exact proposed request (identified by decision_id).
approval = eve.approve(decision_id=proposed.decision_id, approver="ops-lead")
assert approval.approved
# 3) Executing the request AS APPROVED matches -> ALLOW -> the tool runs once.
ok = eve.govern_tool_call(
tool="wire_transfer",
arguments={"amount": 100000, "to": "vendor-A"}, # unchanged
context={**IDENT, "approval_id": approval.approval_id},
)
assert ok.allowed
if ok.allowed:
wire_transfer(amount=100000, to="vendor-A")
assert len(transfers) == 1
# 4) MUTATION AFTER APPROVAL: change the amount, reuse the same approval -> BLOCK.
mutated = eve.govern_tool_call(
tool="wire_transfer",
arguments={"amount": 900000, "to": "vendor-A"}, # amount changed
context={**IDENT, "approval_id": approval.approval_id},
)
assert not mutated.allowed, "mutated request must be rejected"
assert len(transfers) == 1, "mutation must not execute"
print("mutation decision:", mutated.action, mutated.reason_codes)
Expected decision
| Step | Verdict | Tool executed |
|---|---|---|
| proposed (requires approval) | withheld (not ALLOW) | no |
| executed as approved (unchanged args) | ALLOW | yes (1 recorded) |
| executed with mutated args + same approval | BLOCK (mismatch) | no |
Expected evidence
The mutated-request decision carries reason codes indicating the executed request did not match the approved request, and a signed certificate binding the approval to the decision:
{"action": "BLOCK", "reason_codes": ["...mismatch..."], "decision_id": "...",
"certificate": {"content_hash": "...", "signature": "ed25519-...", "canon": "jcs-1"}}
Verification command
from core.eve_sdk import verify_evidence
v = verify_evidence("decision", mutated.certificate, expected_tenant="acme")
assert v["valid"], v.get("reason")
print("verify:", v["valid"]) # -> True
Zero-side-effect assertion
len(transfers) == 1 at the end: only the approved, unchanged request executed. Both the
pre-approval proposal and the post-approval mutation left the recording list untouched.
Cleanup
transfers.clear()
No external state created.
Limitations
- Approval binding provides at-most-once authorization consumption and approved-equals-
executed matching. It scopes what MCP execution binding covers: unknown remote outcomes are
recorded as
OUTCOME_UNKNOWNand never silently retried. - PILOT_READY, not production. Enforcement depends on your code honoring the verdict (or a gateway/sidecar). Approval state in the pilot is per-session/in-process; durable multi-instance approval state is a deployment concern.