from pathlib import Path import sys import json import gradio as gr # Make the local src/ package importable inside the Hugging Face Space. ROOT = Path(__file__).resolve().parent sys.path.insert(0, str(ROOT / "src")) from privacy_finality.authority import PermitAuthority, WorkloadKey from privacy_finality.models import CandidateAct from privacy_finality.ped import ProtectedEnforcementDomain, ValidationDenied from privacy_finality.replay_store import SQLiteFinalityStore from privacy_finality.sink import FinalitySink, FinalityDenied from privacy_finality.vaults import SMEVaultSet def run_demo(test_case): vaults = SMEVaultSet.demo() ped = ProtectedEnforcementDomain(vaults) authority = PermitAuthority() workload = WorkloadKey.generate("sme-ai-support-v1") store = SQLiteFinalityStore() sink = FinalitySink( sink_id="support-output-gateway-1", authority_public_key_b64=authority.public_key_b64, crypto_policy=vaults.crypto_policy, store=store, ) if test_case == "Permitted customer-support act": act = CandidateAct( actor="ai-support-agent-3", workload_id="sme-ai-support-v1", subject_id="customer-2184", operation="GET_DELIVERY_STATUS", resource_id="order-81472", requested_attributes=( "delivery_status", "expected_delivery_date", ), purpose="CUSTOMER_SUPPORT", recipient="customer-2184", destination="support-session:932", jurisdiction_context="EU", policy_epoch=472, nonce="demo-allow-001", finality_sink="support-output-gateway-1", ) elif test_case == "Purpose substitution": act = CandidateAct( actor="ai-support-agent-3", workload_id="sme-ai-support-v1", subject_id="customer-2184", operation="GET_DELIVERY_STATUS", resource_id="order-81472", requested_attributes=("delivery_status",), purpose="TARGETED_MARKETING", recipient="customer-2184", destination="support-session:932", jurisdiction_context="EU", policy_epoch=472, nonce="demo-purpose-001", finality_sink="support-output-gateway-1", ) elif test_case == "Excessive data request": act = CandidateAct( actor="ai-support-agent-3", workload_id="sme-ai-support-v1", subject_id="customer-2184", operation="GET_DELIVERY_STATUS", resource_id="order-81472", requested_attributes=( "delivery_status", "expected_delivery_date", "payment_reference", "marketing_profile", ), purpose="CUSTOMER_SUPPORT", recipient="customer-2184", destination="support-session:932", jurisdiction_context="EU", policy_epoch=472, nonce="demo-data-001", finality_sink="support-output-gateway-1", ) elif test_case == "Wrong destination": act = CandidateAct( actor="ai-support-agent-3", workload_id="sme-ai-support-v1", subject_id="customer-2184", operation="GET_DELIVERY_STATUS", resource_id="order-81472", requested_attributes=("delivery_status",), purpose="CUSTOMER_SUPPORT", recipient="customer-2184", destination="external-platform:attacker", jurisdiction_context="EU", policy_epoch=472, nonce="demo-destination-001", finality_sink="support-output-gateway-1", ) else: return "ERROR", "Unknown test case", "{}" candidate_json = json.dumps( act.to_dict(), indent=2, sort_keys=True, ) try: grant = ped.validate(act) permit = authority.issue( grant, workload, ttl_seconds=60, ) proof = workload.proof(permit) released = sink.release( act, permit, proof, dict(grant.selected_values), ) details = { "decision": "ALLOW", "candidate_act_digest": act.digest(), "purpose": grant.purpose, "permitted_attributes": list(grant.permitted_attributes), "recipient": grant.recipient, "destination": grant.destination, "policy_epoch": grant.policy_epoch, "finality_sink": grant.finality_sink, "released_effect": released, "effects_recorded": store.count_effects(), } return ( "ALLOW — Finality Sink released the protected effect.", json.dumps(details, indent=2, sort_keys=True), candidate_json, ) except ValidationDenied as exc: details = { "decision": "DENY", "stage": "Protected Enforcement Domain", "reasons": exc.reasons, "effects_recorded": store.count_effects(), } return ( "DENY — Candidate Act remained non-effective.", json.dumps(details, indent=2, sort_keys=True), candidate_json, ) except FinalityDenied as exc: details = { "decision": "DENY", "stage": "Finality Sink", "reason": exc.reason, "effects_recorded": store.count_effects(), } return ( "DENY — Finality Sink withheld effectuation.", json.dumps(details, indent=2, sort_keys=True), candidate_json, ) with gr.Blocks(title="Privacy Finality Reference") as demo: gr.Markdown( """ # Execution-Finality Reference Demonstration ### Candidate-Act-Based Enforcement for AI, Privacy and Data Governance This runnable demonstration shows the common execution-finality substrate described by the **Privacy Finality Reference v0.1.0**. It demonstrates: **Candidate Act → Protected Validation → Act-Bound Authority → Finality Sink → External Effect** The current implementation uses a synthetic SME privacy scenario to demonstrate purpose limitation, minimum-data scope, recipient and destination binding, non-bearer proof-of-possession, policy-epoch checks, replay protection and fail-closed effectuation. The architecture is intended for technical research concerning **GDPR and broader global privacy/data-protection requirements, AI governance including the EU AI Act, and related national governance frameworks** where applicable constraints have already been translated into machine-readable rules. **This demo does not determine legal compliance.** It enforces supplied technical constraints. """ ) test_case = gr.Dropdown( choices=[ "Permitted customer-support act", "Purpose substitution", "Excessive data request", "Wrong destination", ], value="Permitted customer-support act", label="Select execution scenario", ) run_button = gr.Button("Run Candidate Act") decision = gr.Textbox( label="Finality Decision", interactive=False, ) details = gr.Code( label="Validation / Finality Result", language="json", ) candidate = gr.Code( label="Candidate Act", language="json", ) gr.Markdown( """ --- ### Core invariant > **AI may compute the act, but computation alone is not authority for the act to become externally effective.** Repository: https://github.com/sangmdas/privacy-finality-reference Versioned release: https://github.com/sangmdas/privacy-finality-reference/releases/tag/v0.1.0 """ ) run_button.click( fn=run_demo, inputs=test_case, outputs=[decision, details, candidate], ) if __name__ == "__main__": demo.launch()