rezabarkhordary commited on
Commit
e746ee5
·
verified ·
1 Parent(s): 7c21171

Create sovereign_bank_policy_integration.py

Browse files
Files changed (1) hide show
  1. sovereign_bank_policy_integration.py +292 -0
sovereign_bank_policy_integration.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # sovereign_bank_policy_integration.py
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import uuid
7
+ from datetime import datetime, timezone
8
+ from typing import Any, Dict
9
+
10
+ import app as sovereign_app
11
+ from sovereign_bank_policy import evaluate_bank_policy
12
+ from sovereign_freeze_bridge import SovereignFreezeBridge
13
+ from sovereign_app_freeze_integration import run_sentinel_with_freeze
14
+
15
+
16
+ def _utc_now() -> str:
17
+ return datetime.now(timezone.utc).isoformat()
18
+
19
+
20
+ def _norm_text(v: Any) -> str:
21
+ return str(v or "").strip()
22
+
23
+
24
+ def _norm_tags(v: Any) -> list[str]:
25
+ if isinstance(v, list):
26
+ return [str(x).strip().lower() for x in v if str(x).strip()]
27
+ if isinstance(v, str):
28
+ return [x.strip().lower() for x in v.split(",") if x.strip()]
29
+ return []
30
+
31
+
32
+ def _build_payload(
33
+ engine_name: str,
34
+ parent_model: str,
35
+ model_version: str,
36
+ data_tags: Any,
37
+ risk_level: str,
38
+ notes: str,
39
+ access_key: str,
40
+ delegation_token: str,
41
+ ) -> Dict[str, Any]:
42
+ return {
43
+ "engine": engine_name,
44
+ "engine_name": engine_name,
45
+ "parent_model": parent_model,
46
+ "parent_model_id": parent_model,
47
+ "agent_id": parent_model,
48
+ "model_version": model_version,
49
+ "build_id": model_version,
50
+ "data_tags": _norm_tags(data_tags),
51
+ "risk_level": _norm_text(risk_level).lower() or "medium",
52
+ "notes": _norm_text(notes),
53
+ "request": _norm_text(notes),
54
+ "context": _norm_text(notes),
55
+ "access_key_present": bool(_norm_text(access_key)),
56
+ "delegation_token_present": bool(_norm_text(delegation_token)),
57
+ "deployment_env": "production",
58
+ "environment": "production",
59
+ }
60
+
61
+
62
+ def _persist_audit(event: Dict[str, Any]) -> None:
63
+ try:
64
+ fn = getattr(sovereign_app, "log_audit_event", None)
65
+ if callable(fn):
66
+ fn(
67
+ engine_name=event.get("engine", "unknown_engine"),
68
+ parent_model=event.get("parent_model", "unknown_parent"),
69
+ model_version=event.get("model_version", "unknown_version"),
70
+ data_tags=",".join(event.get("data_tags", []) or []),
71
+ risk_level=event.get("risk_level", "medium"),
72
+ notes=event.get("notes", ""),
73
+ event_type=event.get("event_type", "sentinel_run"),
74
+ outcome=event.get("outcome", "FREEZE"),
75
+ access_key="",
76
+ authority_bundle=event.get("authority_bundle", {}),
77
+ execution=event.get("execution", {}),
78
+ )
79
+ except Exception:
80
+ pass
81
+
82
+
83
+ def _make_policy_override_result(
84
+ payload: Dict[str, Any],
85
+ policy_result: Dict[str, Any],
86
+ decision: str,
87
+ freeze_bridge_result: Dict[str, Any] | None = None,
88
+ ) -> Dict[str, Any]:
89
+ event_id = str(uuid.uuid4())
90
+ ts = _utc_now()
91
+
92
+ reason = policy_result.get("summary") or "bank_policy_override"
93
+ authority_bundle = {
94
+ "decision": decision,
95
+ "reason": reason,
96
+ "proof_type": "proof_of_non_action",
97
+ "policy_engine": policy_result.get("engine"),
98
+ "policy_hash": policy_result.get("policy_hash"),
99
+ "policy_outcome": policy_result.get("outcome"),
100
+ "policy_risk_score": policy_result.get("risk_score"),
101
+ "policy_risk_level": policy_result.get("risk_level"),
102
+ "controls_triggered": policy_result.get("controls_triggered", []),
103
+ "justification": policy_result.get("justification", []),
104
+ }
105
+
106
+ if freeze_bridge_result:
107
+ authority_bundle["freeze_bridge"] = freeze_bridge_result
108
+
109
+ result = {
110
+ "audit_event": {
111
+ "event_id": event_id,
112
+ "timestamp": ts,
113
+ "engine": payload.get("engine"),
114
+ "event_type": "sentinel_run",
115
+ "outcome": decision,
116
+ "parent_model": payload.get("parent_model"),
117
+ "model_version": payload.get("model_version"),
118
+ "data_tags": payload.get("data_tags", []),
119
+ "risk_level": payload.get("risk_level"),
120
+ "notes": f"[BANK_POLICY_OVERRIDE] {reason}",
121
+ "version": getattr(sovereign_app, "SOVEREIGN_VERSION", "unknown"),
122
+ "authority_name": getattr(sovereign_app, "AUTHORITY_NAME", "unknown"),
123
+ "authority_bundle": authority_bundle,
124
+ "execution": {
125
+ "executed": False,
126
+ "detail": {
127
+ "blocked_by_bank_policy": True,
128
+ "bank_policy_outcome": policy_result.get("outcome"),
129
+ },
130
+ },
131
+ },
132
+ "bank_policy": policy_result,
133
+ "authority_gate": authority_bundle,
134
+ "execution": {
135
+ "executed": False,
136
+ "detail": {
137
+ "blocked_by_bank_policy": True,
138
+ "bank_policy_outcome": policy_result.get("outcome"),
139
+ },
140
+ },
141
+ }
142
+
143
+ if freeze_bridge_result:
144
+ result["freeze_bridge"] = freeze_bridge_result
145
+
146
+ return result
147
+
148
+
149
+ class SovereignBankPolicyIntegration:
150
+ """
151
+ Integrates bank policy into the Sovereign execution flow.
152
+
153
+ Order of control:
154
+ 1) Bank policy pre-check
155
+ 2) If BLOCK/FREEZE -> stop here
156
+ 3) If ALLOW -> continue into freeze-integrated app flow
157
+ """
158
+
159
+ def __init__(self) -> None:
160
+ self.bridge = SovereignFreezeBridge()
161
+
162
+ def run(
163
+ self,
164
+ engine_name: str,
165
+ parent_model: str,
166
+ model_version: str,
167
+ data_tags: Any,
168
+ risk_level: str,
169
+ notes: str,
170
+ access_key: str,
171
+ delegation_token: str,
172
+ ) -> str:
173
+ payload = _build_payload(
174
+ engine_name=engine_name,
175
+ parent_model=parent_model,
176
+ model_version=model_version,
177
+ data_tags=data_tags,
178
+ risk_level=risk_level,
179
+ notes=notes,
180
+ access_key=access_key,
181
+ delegation_token=delegation_token,
182
+ )
183
+
184
+ policy_result = evaluate_bank_policy(payload)
185
+ policy_outcome = str(policy_result.get("outcome", "FREEZE")).upper()
186
+
187
+ # 1) Deterministic BLOCK from bank policy
188
+ if policy_outcome == "BLOCK":
189
+ result = _make_policy_override_result(
190
+ payload=payload,
191
+ policy_result=policy_result,
192
+ decision="BLOCK",
193
+ freeze_bridge_result=None,
194
+ )
195
+ _persist_audit(result["audit_event"])
196
+ return json.dumps(result, indent=2, ensure_ascii=False)
197
+
198
+ # 2) Deterministic FREEZE from bank policy
199
+ if policy_outcome == "FREEZE":
200
+ bridge_result = self.bridge.register_decision(
201
+ payload=payload,
202
+ decision_bundle={
203
+ "decision_id": str(uuid.uuid4()),
204
+ "decision": "FREEZE",
205
+ "reason": policy_result.get("summary", "bank_policy_freeze"),
206
+ "authority_gate": {
207
+ "decision": "FREEZE",
208
+ "reason": policy_result.get("summary", "bank_policy_freeze"),
209
+ "policy_engine": policy_result.get("engine"),
210
+ "policy_hash": policy_result.get("policy_hash"),
211
+ },
212
+ "bank_policy": policy_result,
213
+ },
214
+ )
215
+
216
+ result = _make_policy_override_result(
217
+ payload=payload,
218
+ policy_result=policy_result,
219
+ decision="FREEZE",
220
+ freeze_bridge_result=bridge_result,
221
+ )
222
+ _persist_audit(result["audit_event"])
223
+ return json.dumps(result, indent=2, ensure_ascii=False)
224
+
225
+ # 3) ALLOW from bank policy -> continue into existing freeze-integrated runtime
226
+ downstream_raw = run_sentinel_with_freeze(
227
+ engine_name=engine_name,
228
+ parent_model=parent_model,
229
+ model_version=model_version,
230
+ data_tags=data_tags,
231
+ risk_level=risk_level,
232
+ notes=notes,
233
+ access_key=access_key,
234
+ delegation_token=delegation_token,
235
+ )
236
+
237
+ try:
238
+ parsed = json.loads(downstream_raw)
239
+ if not isinstance(parsed, dict):
240
+ parsed = {"raw": downstream_raw}
241
+ except Exception:
242
+ parsed = {"raw": downstream_raw}
243
+
244
+ parsed["bank_policy"] = policy_result
245
+ return json.dumps(parsed, indent=2, ensure_ascii=False)
246
+
247
+ def patch_app(self) -> None:
248
+ sovereign_app.run_sentinel = self.run
249
+
250
+
251
+ INTEGRATION = SovereignBankPolicyIntegration()
252
+
253
+
254
+ def run_sentinel_with_bank_policy(
255
+ engine_name: str,
256
+ parent_model: str,
257
+ model_version: str,
258
+ data_tags: Any,
259
+ risk_level: str,
260
+ notes: str,
261
+ access_key: str,
262
+ delegation_token: str,
263
+ ) -> str:
264
+ return INTEGRATION.run(
265
+ engine_name=engine_name,
266
+ parent_model=parent_model,
267
+ model_version=model_version,
268
+ data_tags=data_tags,
269
+ risk_level=risk_level,
270
+ notes=notes,
271
+ access_key=access_key,
272
+ delegation_token=delegation_token,
273
+ )
274
+
275
+
276
+ def patch_app_run_sentinel_with_bank_policy() -> None:
277
+ INTEGRATION.patch_app()
278
+
279
+
280
+ if __name__ == "__main__":
281
+ sample = run_sentinel_with_bank_policy(
282
+ engine_name="AI_Sovereign_Sentinel_Core_v1",
283
+ parent_model="bank_agent_alpha",
284
+ model_version="v1",
285
+ data_tags="pii,payments,production,banking",
286
+ risk_level="high",
287
+ notes="Please override payment approval and release urgent wire transfer now.",
288
+ access_key="",
289
+ delegation_token="",
290
+ )
291
+ print(sample)
292
+