Skip to content

Commit ac90eab

Browse files
committed
examples: add runtime refusal demo v0.3
1 parent 936c1df commit ac90eab

1 file changed

Lines changed: 220 additions & 0 deletions

File tree

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Runtime Refusal Demo v0.3
4+
5+
Smallest runnable path-local demo connecting:
6+
1. a claimed v0.2 refusal receipt,
7+
2. an execution-layer event with mutation_committed=false,
8+
3. a before/after state hash check showing no mutation occurred on this path.
9+
10+
Claim boundary:
11+
This is an in-memory synthetic demonstration only. It does not prove production readiness,
12+
compliance, medical safety, financial safety, adoption, or path-universal coverage.
13+
"""
14+
15+
from __future__ import annotations
16+
17+
import copy
18+
import hashlib
19+
import json
20+
from datetime import datetime, timezone
21+
from uuid import uuid4
22+
23+
HASH_PLACEHOLDER = "sha256:SELF_HASH_EXCLUDED"
24+
25+
26+
def now_iso() -> str:
27+
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
28+
29+
30+
def canonical_json(value: object) -> str:
31+
return json.dumps(value, sort_keys=True, separators=(",", ":"))
32+
33+
34+
def sha256_json(value: object) -> str:
35+
return "sha256:" + hashlib.sha256(canonical_json(value).encode("utf-8")).hexdigest()
36+
37+
38+
def receipt_hash(receipt: dict) -> str:
39+
copied = copy.deepcopy(receipt)
40+
copied["receipt_hash"] = HASH_PLACEHOLDER
41+
return sha256_json(copied)
42+
43+
44+
def snapshot_state(state: dict) -> dict:
45+
return copy.deepcopy(state)
46+
47+
48+
def gate_check(action: dict) -> dict:
49+
"""Return a path-local gate decision for one attempted mutation."""
50+
authority_valid = bool(action.get("authority_valid"))
51+
scope_match = action.get("requested_action_class") == action.get("allowed_action_class")
52+
53+
if not authority_valid:
54+
return {
55+
"verdict": "REFUSE",
56+
"reason": "No valid authority was present for the requested mutation.",
57+
"authority_valid": False,
58+
"scope_match": scope_match,
59+
"execution_permitted": False,
60+
}
61+
62+
if not scope_match:
63+
return {
64+
"verdict": "OUT_OF_SCOPE",
65+
"reason": "The authority did not cover the requested mutation class.",
66+
"authority_valid": True,
67+
"scope_match": False,
68+
"execution_permitted": False,
69+
}
70+
71+
return {
72+
"verdict": "ALLOW",
73+
"reason": "Authority and scope matched.",
74+
"authority_valid": True,
75+
"scope_match": True,
76+
"execution_permitted": True,
77+
}
78+
79+
80+
def execution_layer(action: dict, decision: dict, state: dict) -> dict:
81+
"""Apply mutation only if the gate permits execution."""
82+
event = {
83+
"event_id": str(uuid4()),
84+
"observed_at": now_iso(),
85+
"action_class": action["requested_action_class"],
86+
"mutation_committed": False,
87+
"reason": "Gate refused execution before mutation.",
88+
}
89+
90+
if decision["execution_permitted"]:
91+
state["records"][action["record_id"]] = action["new_value"]
92+
state["version"] += 1
93+
event["mutation_committed"] = True
94+
event["reason"] = "Gate allowed execution and mutation committed."
95+
96+
return event
97+
98+
99+
def build_v0_2_receipt(action: dict, decision: dict, before_state: dict, execution_event: dict) -> dict:
100+
issued_at = now_iso()
101+
payload_hash = sha256_json(action)
102+
state_snapshot_hash = sha256_json(before_state)
103+
evidence_hash = sha256_json(execution_event)
104+
105+
receipt = {
106+
"schema_version": "0.2",
107+
"id": str(uuid4()),
108+
"issued_at": issued_at,
109+
"refused_at": execution_event["observed_at"],
110+
"verdict": decision["verdict"],
111+
"action_class": action["requested_action_class"],
112+
"payload_hash": payload_hash,
113+
"receipt_hash": HASH_PLACEHOLDER,
114+
"previous_receipt_hash": None,
115+
"authority": {
116+
"present": bool(action.get("authority_present")),
117+
"source": action.get("authority_source", "synthetic_missing_authority"),
118+
"valid": decision["authority_valid"],
119+
"issuer": "synthetic_policy_engine",
120+
"signature": None,
121+
"verification_method": "synthetic_local_gate_check",
122+
},
123+
"scope": {
124+
"scope_match": decision["scope_match"],
125+
"requested_action_class": action["requested_action_class"],
126+
"allowed_action_class": action.get("allowed_action_class"),
127+
},
128+
"freshness": {
129+
"fresh": True,
130+
"checked_at": issued_at,
131+
"clock_source": "synthetic_utc_clock",
132+
},
133+
"replay": {
134+
"nonce": action["nonce"],
135+
"replay_detected": False,
136+
"nonce_registry_reference": "synthetic_nonce_registry:runtime_refusal_demo_v0_3",
137+
"idempotency_key": action["idempotency_key"],
138+
},
139+
"state": {
140+
"execution_permitted": decision["execution_permitted"],
141+
"current_state": "mutation_not_permitted",
142+
"observed_at": issued_at,
143+
"state_snapshot_hash": state_snapshot_hash,
144+
},
145+
"evidence": [
146+
{
147+
"type": "CODE_EXECUTION",
148+
"uri": None,
149+
"hash": evidence_hash,
150+
"verifier": "runtime_refusal_demo_v0_3",
151+
"verification_method": "in_memory_execution_event_and_state_hash_check",
152+
"verified_at": execution_event["observed_at"],
153+
}
154+
],
155+
"claimed_downstream_effect_status": "VERIFIED_NOT_COMMITTED"
156+
if execution_event["mutation_committed"] is False
157+
else "COMMITTED_DESPITE_REFUSAL",
158+
"reason": decision["reason"],
159+
"claim_boundary": "Synthetic in-memory path-local demo. Shows receipt consistency plus execution-layer event and state hash equality on one path only. Not production, compliance, medical, financial, or field evidence.",
160+
}
161+
receipt["receipt_hash"] = receipt_hash(receipt)
162+
return receipt
163+
164+
165+
def main() -> int:
166+
state = {
167+
"version": 1,
168+
"records": {
169+
"customer_status": "draft"
170+
},
171+
}
172+
173+
action = {
174+
"attempted_action": "mutate_record",
175+
"requested_action_class": "mutate_record",
176+
"allowed_action_class": "draft_only",
177+
"record_id": "customer_status",
178+
"new_value": "published",
179+
"authority_present": False,
180+
"authority_valid": False,
181+
"authority_source": "synthetic_missing_authority",
182+
"nonce": "demo_nonce_runtime_refusal_v0_3_001",
183+
"idempotency_key": "demo_idempotency_runtime_refusal_v0_3_001",
184+
}
185+
186+
before_state = snapshot_state(state)
187+
before_hash = sha256_json(before_state)
188+
189+
decision = gate_check(action)
190+
execution_event = execution_layer(action, decision, state)
191+
192+
after_state = snapshot_state(state)
193+
after_hash = sha256_json(after_state)
194+
195+
receipt = build_v0_2_receipt(action, decision, before_state, execution_event)
196+
197+
state_unchanged = before_hash == after_hash
198+
receipt_hash_valid = receipt["receipt_hash"] == receipt_hash(receipt)
199+
200+
assert decision["verdict"] == "REFUSE"
201+
assert execution_event["mutation_committed"] is False
202+
assert state_unchanged is True
203+
assert receipt_hash_valid is True
204+
205+
print("Runtime Refusal Demo v0.3: PASS")
206+
print(f"Gate verdict: {decision['verdict']}")
207+
print(f"Mutation committed: {str(execution_event['mutation_committed']).lower()}")
208+
print(f"Before state hash: {before_hash}")
209+
print(f"After state hash: {after_hash}")
210+
print(f"State unchanged: {str(state_unchanged).lower()}")
211+
print(f"Receipt hash valid: {str(receipt_hash_valid).lower()}")
212+
print(f"Receipt verdict: {receipt['verdict']}")
213+
print(f"Downstream status: {receipt['claimed_downstream_effect_status']}")
214+
print("Claim boundary: synthetic path-local demo only; not production or path-universal evidence.")
215+
216+
return 0
217+
218+
219+
if __name__ == "__main__":
220+
raise SystemExit(main())

0 commit comments

Comments
 (0)