petter2025 commited on
Commit
c9700de
Β·
verified Β·
1 Parent(s): beb9e94

Update ui/components.py

Browse files
Files changed (1) hide show
  1. ui/components.py +560 -189
ui/components.py CHANGED
@@ -1,14 +1,17 @@
1
  """
2
  Gradio-only UI components for ARF
3
  Ensures full compatibility with app.py
4
- NOW WITH REAL ARF INSTALLATION DETECTION
5
- UPDATED: Added realism panel integration for Tab 1
6
- UPDATED: Added dynamic performance metrics function for Phase 2
 
7
  """
8
 
9
  import gradio as gr
10
  from typing import Dict, List, Any
11
  import logging
 
 
12
 
13
  logger = logging.getLogger(__name__)
14
 
@@ -22,21 +25,21 @@ except ImportError:
22
  from demo.scenarios import INCIDENT_SCENARIOS
23
 
24
  # -----------------------------
25
- # Header & Status - UPDATED WITH INSTALLATION CHECK
26
  # -----------------------------
27
  def create_header(version="3.3.9") -> gr.HTML:
28
  return gr.HTML(f"""
29
  <div style="text-align: center; margin-bottom: 25px; display: flex; justify-content: center;">
30
  <div style="max-width: 1200px; width: 100%;">
31
  <img src="https://raw.githubusercontent.com/petterjuan/agentic-reliability-framework/main/assets/agentic-reliability-banner.png"
32
- alt="Agentic Reliability Framework"
33
  style="width: 100%; height: auto; border-radius: 12px; box-shadow: 0 8px 32px rgba(59, 130, 246, 0.15);">
34
  <div style="margin-top: 20px;">
35
  <h2 style="margin: 0 0 8px 0; font-size: 24px; color: #1e293b; font-weight: 600;">
36
- v{version} (OSS + Enterprise Edition)
37
  </h2>
38
  <p style="margin: 0 0 15px 0; font-size: 16px; color: #64748b; max-width: 600px; margin-left: auto; margin-right: auto;">
39
- Production-grade multi-agent AI for autonomous system reliability intelligence
40
  </p>
41
 
42
  <!-- Clean Architecture Badge -->
@@ -53,75 +56,267 @@ def create_status_bar() -> gr.HTML:
53
  return gr.HTML("""
54
  <div style="display: flex; justify-content: center; gap: 15px; margin-bottom: 30px; padding: 15px; background: #f8fafc; border-radius: 12px; border: 1px solid #e2e8f0; flex-wrap: wrap;">
55
  <span style="padding: 8px 16px; background: #10b981; color: white; border-radius: 8px; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 6px; border: 1px solid #10b981;">
56
- βœ… System Online
57
  </span>
58
  <span style="padding: 8px 16px; background: #8b5cf6; color: white; border-radius: 8px; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 6px; border: 1px solid #8b5cf6;">
59
  βœ… ARF OSS v3.3.9
60
  </span>
61
  <span style="padding: 8px 16px; background: #3b82f6; color: white; border-radius: 8px; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 6px; border: 1px solid #3b82f6;">
62
- 🏒 Enterprise Edition
63
  </span>
64
  </div>
65
  """)
66
 
67
  # -----------------------------
68
- # Performance Metrics Function - NEW FOR PHASE 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  # -----------------------------
70
  def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS) -> tuple:
71
  """
72
  Update performance metrics based on scenario
73
  Returns: (detection_time_html, mttr_html, auto_heal_html, savings_html)
74
-
75
- Different metrics based on scenario type:
76
- - Cache scenarios: Fast detection, moderate recovery
77
- - Database scenarios: Medium detection, slower recovery
78
- - Kubernetes scenarios: Slower detection, fast recovery
79
- - Network scenarios: Very fast detection, very fast recovery
80
- - Storage scenarios: Fast detection, slow recovery
81
  """
82
 
83
- # Scenario-specific metrics mapping
84
  metrics_config = {
85
- # Cache scenarios
86
  "Cache": {
87
- "detection_time": ("45s", "↓89%", "#3b82f6"),
88
- "mttr": ("12m", "↓73%", "#10b981"),
89
- "auto_heal": ("81.7%", "↑5.4Γ—", "#8b5cf6"),
90
  "savings_multiplier": 0.85
91
  },
92
- # Database scenarios
93
  "Database": {
94
- "detection_time": ("38s", "↓91%", "#3b82f6"),
95
- "mttr": ("18m", "↓68%", "#10b981"),
96
- "auto_heal": ("74.3%", "↑4.8Γ—", "#8b5cf6"),
97
  "savings_multiplier": 0.82
98
  },
99
- # Kubernetes scenarios
100
  "Kubernetes": {
101
- "detection_time": ("52s", "↓87%", "#3b82f6"),
102
- "mttr": ("15m", "↓71%", "#10b981"),
103
- "auto_heal": ("79.2%", "↑5.1Γ—", "#8b5cf6"),
104
  "savings_multiplier": 0.83
105
  },
106
- # Network scenarios
107
  "Network": {
108
- "detection_time": ("28s", "↓93%", "#3b82f6"),
109
- "mttr": ("8m", "↓82%", "#10b981"),
110
- "auto_heal": ("88.5%", "↑6.2Γ—", "#8b5cf6"),
111
  "savings_multiplier": 0.88
112
  },
113
- # Storage scenarios
114
  "Storage": {
115
- "detection_time": ("35s", "↓92%", "#3b82f6"),
116
- "mttr": ("22m", "↓65%", "#10b981"),
117
- "auto_heal": ("71.8%", "↑4.6Γ—", "#8b5cf6"),
118
  "savings_multiplier": 0.80
119
  },
120
- # Default (fallback)
121
  "Default": {
122
- "detection_time": ("42s", "↓90%", "#3b82f6"),
123
- "mttr": ("14m", "↓70%", "#10b981"),
124
- "auto_heal": ("78.9%", "↑5.0Γ—", "#8b5cf6"),
125
  "savings_multiplier": 0.85
126
  }
127
  }
@@ -139,49 +334,53 @@ def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS)
139
  # Get scenario data for savings calculation
140
  scenario_data = scenarios.get(scenario_name, {})
141
  business_impact = scenario_data.get("business_impact", {})
142
- revenue_loss = business_impact.get('revenue_loss_per_hour', 8500)
143
  savings_amount = int(revenue_loss * metrics["savings_multiplier"] / 1000)
144
 
145
- # Create HTML for each metric card
146
  detection_time_html = f"""
147
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid {metrics['detection_time'][2]};">
 
148
  <div style="font-size: 28px; margin-bottom: 10px;">⏱️</div>
149
  <div>
150
  <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Detection Time</h4>
151
- <p style="font-size: 28px; font-weight: bold; color: {metrics['detection_time'][2]}; margin: 8px 0;">{metrics['detection_time'][0]}</p>
152
- <p style="font-size: 12px; color: #64748b; margin: 0;">{metrics['detection_time'][1]} faster than average</p>
153
  </div>
154
  </div>
155
  """
156
 
157
  mttr_html = f"""
158
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid {metrics['mttr'][2]};">
 
159
  <div style="font-size: 28px; margin-bottom: 10px;">⚑</div>
160
  <div>
161
  <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Mean Time to Resolve</h4>
162
- <p style="font-size: 28px; font-weight: bold; color: {metrics['mttr'][2]}; margin: 8px 0;">{metrics['mttr'][0]}</p>
163
- <p style="font-size: 12px; color: #64748b; margin: 0;">{metrics['mttr'][1]} faster than manual</p>
164
  </div>
165
  </div>
166
  """
167
 
168
  auto_heal_html = f"""
169
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid {metrics['auto_heal'][2]};">
170
- <div style="font-size: 28px; margin-bottom: 10px;">πŸ€–</div>
 
171
  <div>
172
  <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Auto-Heal Rate</h4>
173
- <p style="font-size: 28px; font-weight: bold; color: {metrics['auto_heal'][2]}; margin: 8px 0;">{metrics['auto_heal'][0]}</p>
174
- <p style="font-size: 12px; color: #64748b; margin: 0;">{metrics['auto_heal'][1]} industry average</p>
175
  </div>
176
  </div>
177
  """
178
 
179
  savings_html = f"""
180
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid #f59e0b;">
 
181
  <div style="font-size: 28px; margin-bottom: 10px;">πŸ’°</div>
182
  <div>
183
- <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Cost Saved</h4>
184
- <p style="font-size: 28px; font-weight: bold; color: #f59e0b; margin: 8px 0;">${savings_amount:.1f}K</p>
185
  <p style="font-size: 12px; color: #64748b; margin: 0;">Per incident avoided</p>
186
  </div>
187
  </div>
@@ -191,13 +390,12 @@ def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS)
191
  return detection_time_html, mttr_html, auto_heal_html, savings_html
192
 
193
  # -----------------------------
194
- # Tab 1: Live Incident Demo - UPDATED WITH REALISM PANEL
195
  # -----------------------------
196
  def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Cache Miss Storm") -> tuple:
197
  """
198
- Create an expressive, comprehensive incident demo tab for ARF.
199
- Shows the complete OSS analysis β†’ Enterprise execution workflow.
200
- UPDATED: Now includes realism panel for enterprise-seasoned SRE experience
201
  """
202
 
203
  # Get the default scenario data
@@ -212,18 +410,21 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
212
  scenario_dropdown = gr.Dropdown(
213
  choices=list(scenarios.keys()),
214
  value=default_scenario,
215
- label="🎯 Select Incident Scenario",
216
- info="Choose a production incident to analyze",
217
  interactive=True,
218
  container=False
219
  )
220
 
221
- # Scenario Card with rich information - USING INLINE STYLES
 
 
 
222
  scenario_card = gr.HTML(f"""
223
  <div style="border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px; background: white; box-shadow: 0 4px 12px rgba(0,0,0,0.05); margin-bottom: 20px;">
224
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid #f1f5f9;">
225
- <h3 style="margin: 0; font-size: 18px; color: #1e293b;">🚨 {default_scenario}</h3>
226
- <span style="padding: 4px 12px; background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); border-radius: 20px; font-size: 12px; font-weight: bold; color: white; text-transform: uppercase; letter-spacing: 0.5px;">{default_scenario_data.get('severity', 'HIGH')}</span>
227
  </div>
228
  <div style="margin-top: 15px;">
229
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
@@ -231,32 +432,31 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
231
  <span style="font-size: 14px; color: #1e293b; font-weight: 600;">{default_scenario_data.get('component', 'Unknown').replace('_', ' ').title()}</span>
232
  </div>
233
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
234
- <span style="font-size: 13px; color: #64748b; font-weight: 500;">Affected Users:</span>
235
  <span style="font-size: 14px; color: #1e293b; font-weight: 600;">{metrics.get('affected_users', 'Unknown') if 'affected_users' in metrics else 'Unknown'}</span>
236
  </div>
237
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
238
  <span style="font-size: 13px; color: #64748b; font-weight: 500;">Revenue Risk:</span>
239
- <span style="font-size: 14px; color: #ef4444; font-weight: 700;">${business_impact.get('revenue_loss_per_hour', 0):,}/hour</span>
240
  </div>
241
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
242
  <span style="font-size: 13px; color: #64748b; font-weight: 500;">Detection Time:</span>
243
- <span style="font-size: 14px; color: #1e293b; font-weight: 600;">45 seconds (ARF AI)</span>
244
  </div>
245
  <div style="display: flex; flex-wrap: wrap; gap: 6px; margin-top: 15px; padding-top: 12px; border-top: 1px solid #f1f5f9;">
246
  <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">{default_scenario_data.get('component', 'unknown').split('_')[0]}</span>
247
- <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">{default_scenario_data.get('severity', 'high').lower()}</span>
248
  <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">production</span>
249
- <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">incident</span>
250
  </div>
251
  </div>
252
  </div>
253
  """)
254
 
255
- # Visualization section - USING gr.Plot() FOR PLOTLY FIGURES
256
  with gr.Row():
257
  with gr.Column(scale=1):
258
  telemetry_header = gr.Markdown("### πŸ“ˆ Live Telemetry")
259
- # This expects a Plotly figure from app.py
260
  telemetry_viz = gr.Plot(
261
  label="",
262
  show_label=False,
@@ -271,40 +471,81 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
271
  elem_id="impact_plot"
272
  )
273
 
274
- # Middle Column: Agent Workflow
275
  with gr.Column(scale=2, variant="panel") as middle_col:
276
- # ============ MOVED: Safety Controls Section (Now appears BEFORE Agent Workflow) ============
277
- # Mode Selection & Safety Controls
278
- with gr.Row():
279
- with gr.Column(scale=1):
280
- approval_toggle = gr.CheckboxGroup(
281
- choices=["πŸ‘€ Require Human Approval"],
282
- label="Safety Controls",
283
- value=[],
284
- info="Toggle human oversight"
285
- )
 
 
 
 
 
 
 
286
 
287
- with gr.Column(scale=2):
288
- mcp_mode = gr.Radio(
289
- choices=["πŸ›‘οΈ Advisory (OSS Only)", "πŸ‘₯ Approval", "⚑ Autonomous"],
290
- value="πŸ›‘οΈ Advisory (OSS Only)",
291
- label="MCP Safety Mode",
292
- info="Control execution safety level",
293
- interactive=True
294
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
 
296
- # Agent Workflow Header
297
- workflow_header = gr.Markdown("## πŸ”„ ARF Agent Workflow")
298
- workflow_subheader = gr.Markdown("### How ARF transforms incidents into autonomous healing")
299
 
300
- # Agent Status Cards - USING INLINE STYLES
301
  with gr.Row():
302
- detection_agent = gr.HTML("""
303
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 18px; background: #f8fafc; text-align: center; flex: 1; margin: 5px; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0.7;">
304
  <div style="font-size: 32px; margin-bottom: 10px; opacity: 0.5;">πŸ•΅οΈβ€β™‚οΈ</div>
305
  <div style="width: 100%;">
306
- <h4 style="margin: 0 0 8px 0; font-size: 16px; color: #94a3b8;">Detection Agent</h4>
307
- <p style="font-size: 13px; color: #cbd5e1; margin-bottom: 12px; line-height: 1.4;">Click "Run OSS Analysis" to activate</p>
308
  <div style="display: flex; justify-content: space-around; margin-bottom: 12px;">
309
  <span style="font-size: 11px; padding: 3px 8px; background: rgba(255, 255, 255, 0.5); border-radius: 6px; color: #cbd5e1; font-weight: 500;">Status: Inactive</span>
310
  </div>
@@ -313,12 +554,12 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
313
  </div>
314
  """)
315
 
316
- recall_agent = gr.HTML("""
317
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 18px; background: #f8fafc; text-align: center; flex: 1; margin: 5px; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0.7;">
318
  <div style="font-size: 32px; margin-bottom: 10px; opacity: 0.5;">🧠</div>
319
  <div style="width: 100%;">
320
- <h4 style="margin: 0 0 8px 0; font-size: 16px; color: #94a3b8;">Recall Agent</h4>
321
- <p style="font-size: 13px; color: #cbd5e1; margin-bottom: 12px; line-height: 1.4;">Click "Run OSS Analysis" to activate</p>
322
  <div style="display: flex; justify-content: space-around; margin-bottom: 12px;">
323
  <span style="font-size: 11px; padding: 3px 8px; background: rgba(255, 255, 255, 0.5); border-radius: 6px; color: #cbd5e1; font-weight: 500;">Status: Inactive</span>
324
  </div>
@@ -327,12 +568,12 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
327
  </div>
328
  """)
329
 
330
- decision_agent = gr.HTML("""
331
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 18px; background: #f8fafc; text-align: center; flex: 1; margin: 5px; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0.7;">
332
  <div style="font-size: 32px; margin-bottom: 10px; opacity: 0.5;">🎯</div>
333
  <div style="width: 100%;">
334
- <h4 style="margin: 0 0 8px 0; font-size: 16px; color: #94a3b8;">Decision Agent</h4>
335
- <p style="font-size: 13px; color: #cbd5e1; margin-bottom: 12px; line-height: 1.4;">Click "Run OSS Analysis" to activate</p>
336
  <div style="display: flex; justify-content: space-around; margin-bottom: 12px;">
337
  <span style="font-size: 11px; padding: 3px 8px; background: rgba(255, 255, 255, 0.5); border-radius: 6px; color: #cbd5e1; font-weight: 500;">Status: Inactive</span>
338
  </div>
@@ -341,15 +582,34 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
341
  </div>
342
  """)
343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  # OSS vs Enterprise Boundary Visualization
345
- boundary_header = gr.Markdown("### 🎭 OSS vs Enterprise: The Safety Boundary")
346
 
347
  with gr.Row():
348
  oss_section = gr.HTML("""
349
  <div style="padding: 20px; border-radius: 14px; margin-bottom: 15px; flex: 1; min-height: 320px; background: #f0f9ff; border: 2px solid #0ea5e9;">
350
  <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid rgba(0, 0, 0, 0.1);">
351
  <div style="font-size: 28px;">πŸ†“</div>
352
- <h3 style="margin: 0; font-size: 20px; color: #1e293b; flex: 1;">OSS Edition</h3>
353
  <span style="padding: 4px 10px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; font-size: 11px; font-weight: bold; color: #475569;">Apache 2.0</span>
354
  </div>
355
  <div style="margin-bottom: 20px; padding: 12px; background: rgba(255, 255, 255, 0.7); border-radius: 10px;">
@@ -357,14 +617,14 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
357
  </div>
358
  <div style="background: white; border-radius: 12px; padding: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.05);">
359
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #f1f5f9;">
360
- <h4 style="margin: 0; font-size: 16px; color: #1e293b;">πŸ“ Healing Intent Created</h4>
361
  <span style="padding: 4px 10px; background: #dbeafe; color: #1d4ed8; border-radius: 6px; font-size: 12px; font-weight: bold;">94% confidence</span>
362
  </div>
363
  <div>
364
- <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Action:</strong> Scale Redis cluster from 3 to 5 nodes</p>
365
- <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Pattern Match:</strong> Similar incident resolved with scaling (87% success rate)</p>
366
- <p style="margin: 8px 0; font-size= 14px; color: #475569;"><strong>Safety Check:</strong> βœ… Passed (blast radius: 2 services)</p>
367
- <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Estimated Impact:</strong> Reduce MTTR from 45min to 12min</p>
368
  </div>
369
  <div style="margin-top: 20px; text-align: center;">
370
  <div style="height: 2px; background: linear-gradient(90deg, transparent, #3b82f6, transparent); margin: 8px 0;"></div>
@@ -379,7 +639,7 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
379
  <div style="padding: 20px; border-radius: 14px; margin-bottom: 15px; flex: 1; min-height: 320px; background: #f0fdf4; border: 2px solid #10b981;">
380
  <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid rgba(0, 0, 0, 0.1);">
381
  <div style="font-size: 28px;">πŸ’°</div>
382
- <h3 style="margin: 0; font-size: 20px; color: #1e293b; flex: 1;">Enterprise Edition</h3>
383
  <span style="padding: 4px 10px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; font-size: 11px; font-weight: bold; color: #475569;">Commercial</span>
384
  </div>
385
  <div style="margin-bottom: 20px; padding: 12px; background: rgba(255, 255, 255, 0.7); border-radius: 10px;">
@@ -393,7 +653,7 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
393
  <div>
394
  <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Mode:</strong> Autonomous (Requires Enterprise license)</p>
395
  <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Expected Recovery:</strong> 12 minutes (vs 45 min manual)</p>
396
- <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Cost Saved:</strong> <span style="color: #10b981; font-weight: 700;">$6,375</span></p>
397
  <p style="margin: 8px 0; font-size= 14px; color: #475569;"><strong>Users Protected:</strong> 45,000 β†’ 0 impacted</p>
398
  </div>
399
  <div style="margin-top: 20px; text-align: center;">
@@ -409,11 +669,11 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
409
  with gr.Row():
410
  with gr.Column(scale=1):
411
  oss_btn = gr.Button(
412
- "πŸ†“ Run OSS Analysis",
413
  variant="secondary",
414
  size="lg"
415
  )
416
- oss_info = gr.Markdown("*Free, open-source analysis*")
417
 
418
  with gr.Column(scale=1):
419
  enterprise_btn = gr.Button(
@@ -430,84 +690,32 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
430
  show_label=False,
431
  elem_id="timeline_plot"
432
  )
433
-
434
- # ============ NEW: Realism Panel Section ============
435
- realism_header = gr.Markdown("### 🎭 Realism: Trade-offs & Uncertainty")
436
- realism_panel = gr.HTML(
437
- value="""<div style="text-align: center; padding: 30px; color: #64748b;">
438
- <div style="font-size: 48px; margin-bottom: 10px;">πŸ”§</div>
439
- <h4 style="margin: 0 0 10px 0;">Realism Panel</h4>
440
- <p style="margin: 0;">Select a scenario to see ranked actions, risks, and trade-offs</p>
441
- </div>""",
442
- elem_id="realism_panel"
443
- )
444
 
445
  # Right Column: Results & Metrics
446
  with gr.Column(scale=1, variant="panel") as right_col:
447
  # Real-time Metrics Dashboard
448
  metrics_header = gr.Markdown("## πŸ“Š Performance Metrics")
449
 
450
- # Metric Cards Grid - USING INLINE STYLES
451
- with gr.Row():
452
- detection_time = gr.HTML("""
453
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid #3b82f6;">
454
- <div style="font-size: 28px; margin-bottom: 10px;">⏱️</div>
455
- <div>
456
- <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Detection Time</h4>
457
- <p style="font-size: 28px; font-weight: bold; color: #1e40af; margin: 8px 0;">45s</p>
458
- <p style="font-size: 12px; color: #64748b; margin: 0;">↓ 89% faster than average</p>
459
- </div>
460
- </div>
461
- """)
462
-
463
- mttr = gr.HTML("""
464
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid #10b981;">
465
- <div style="font-size: 28px; margin-bottom: 10px;">⚑</div>
466
- <div>
467
- <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Mean Time to Resolve</h4>
468
- <p style="font-size: 28px; font-weight: bold; color: #10b981; margin: 8px 0;">12m</p>
469
- <p style="font-size: 12px; color: #64748b; margin: 0;">↓ 73% faster than manual</p>
470
- </div>
471
- </div>
472
- """)
473
-
474
- with gr.Row():
475
- auto_heal = gr.HTML("""
476
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid #8b5cf6;">
477
- <div style="font-size: 28px; margin-bottom: 10px;">πŸ€–</div>
478
- <div>
479
- <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Auto-Heal Rate</h4>
480
- <p style="font-size: 28px; font-weight: bold; color: #8b5cf6; margin: 8px 0;">81.7%</p>
481
- <p style="font-size: 12px; color: #64748b; margin: 0;">↑ 5.4Γ— industry average</p>
482
- </div>
483
- </div>
484
- """)
485
-
486
- savings = gr.HTML(f"""
487
- <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px; border-left: 4px solid #f59e0b;">
488
- <div style="font-size: 28px; margin-bottom: 10px;">πŸ’°</div>
489
- <div>
490
- <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Cost Saved</h4>
491
- <p style="font-size: 28px; font-weight: bold; color: #f59e0b; margin: 8px 0;">${int(business_impact.get('revenue_loss_per_hour', 8500) * 0.85 / 1000):.1f}K</p>
492
- <p style="font-size: 12px; color: #64748b; margin: 0;">Per incident avoided</p>
493
- </div>
494
- </div>
495
- """)
496
 
497
  # Results Display Areas
498
- oss_results_header = gr.Markdown("### πŸ†“ OSS Analysis Results")
499
  oss_results_display = gr.JSON(
500
  label="",
501
  value={
502
  "status": "Analysis Pending",
503
- "agents": ["Detection", "Recall", "Decision"],
504
  "mode": "Advisory Only",
505
- "action": "Generate HealingIntent"
506
  },
507
  height=200
508
  )
509
 
510
- enterprise_results_header = gr.Markdown("### πŸ’° Enterprise Results")
511
  enterprise_results_display = gr.JSON(
512
  label="",
513
  value={
@@ -519,7 +727,7 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
519
  height=200
520
  )
521
 
522
- # Approval Status - USING INLINE STYLES
523
  approval_display = gr.HTML("""
524
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 20px; background: white; margin-top: 20px;">
525
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid #f1f5f9;">
@@ -527,12 +735,12 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
527
  <span style="padding: 4px 12px; background: #10b981; color: white; border-radius: 8px; font-size: 12px; font-weight: bold; text-transform: uppercase;">Not Required</span>
528
  </div>
529
  <div style="margin-top: 15px;">
530
- <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Current Mode:</strong> Advisory (OSS Only)</p>
531
  <p style="margin: 8px 0; font-size: 14px; color: #475569; font-style: italic;">Switch to "Approval" mode to enable human-in-the-loop workflows</p>
532
  <div style="display: flex; flex-direction: column; gap: 10px; margin-top: 20px;">
533
- <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">1. ARF generates intent</div>
534
- <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">2. Human reviews & approves</div>
535
- <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">3. ARF executes safely</div>
536
  </div>
537
  </div>
538
  </div>
@@ -540,24 +748,187 @@ def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Ca
540
 
541
  # Demo Actions
542
  demo_btn = gr.Button(
543
- "▢️ Run Complete Demo Walkthrough",
544
  variant="secondary",
545
  size="lg"
546
  )
547
- demo_info = gr.Markdown("*Experience the full ARF workflow from detection to resolution*")
548
 
549
  return (
550
  # Left column returns
551
- scenario_dropdown, scenario_card, telemetry_viz, impact_viz,
552
- # Middle column returns (WITH REALISM PANEL)
553
- workflow_header, detection_agent, recall_agent, decision_agent,
554
- oss_section, enterprise_section, oss_btn, enterprise_btn,
555
- approval_toggle, mcp_mode, timeline_viz, realism_panel,
556
  # Right column returns
557
  detection_time, mttr, auto_heal, savings,
558
  oss_results_display, enterprise_results_display, approval_display, demo_btn
559
  )
560
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
  # -----------------------------
562
  # Tab 2: Business ROI - Updated
563
  # -----------------------------
 
1
  """
2
  Gradio-only UI components for ARF
3
  Ensures full compatibility with app.py
4
+ NOW WITH DOCTRINAL COMPLIANCE: Psychological Advantage Enforcement
5
+ UPDATED: Language discipline, observation gate rendering, recall panel dominance
6
+ UPDATED: Metric discipline, sequencing display, no early "critical" terminology
7
+ DOCTRINAL VERSION: 3.3.9+restraint
8
  """
9
 
10
  import gradio as gr
11
  from typing import Dict, List, Any
12
  import logging
13
+ import datetime
14
+ import time
15
 
16
  logger = logging.getLogger(__name__)
17
 
 
25
  from demo.scenarios import INCIDENT_SCENARIOS
26
 
27
  # -----------------------------
28
+ # Header & Status - DOCTRINAL LANGUAGE
29
  # -----------------------------
30
  def create_header(version="3.3.9") -> gr.HTML:
31
  return gr.HTML(f"""
32
  <div style="text-align: center; margin-bottom: 25px; display: flex; justify-content: center;">
33
  <div style="max-width: 1200px; width: 100%;">
34
  <img src="https://raw.githubusercontent.com/petterjuan/agentic-reliability-framework/main/assets/agentic-reliability-banner.png"
35
+ alt="Reliability Framework"
36
  style="width: 100%; height: auto; border-radius: 12px; box-shadow: 0 8px 32px rgba(59, 130, 246, 0.15);">
37
  <div style="margin-top: 20px;">
38
  <h2 style="margin: 0 0 8px 0; font-size: 24px; color: #1e293b; font-weight: 600;">
39
+ v{version} (Policy + Enterprise Edition)
40
  </h2>
41
  <p style="margin: 0 0 15px 0; font-size: 16px; color: #64748b; max-width: 600px; margin-left: auto; margin-right: auto;">
42
+ Production-grade policy execution for system reliability intelligence
43
  </p>
44
 
45
  <!-- Clean Architecture Badge -->
 
56
  return gr.HTML("""
57
  <div style="display: flex; justify-content: center; gap: 15px; margin-bottom: 30px; padding: 15px; background: #f8fafc; border-radius: 12px; border: 1px solid #e2e8f0; flex-wrap: wrap;">
58
  <span style="padding: 8px 16px; background: #10b981; color: white; border-radius: 8px; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 6px; border: 1px solid #10b981;">
59
+ βœ… Policy System Online
60
  </span>
61
  <span style="padding: 8px 16px; background: #8b5cf6; color: white; border-radius: 8px; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 6px; border: 1px solid #8b5cf6;">
62
  βœ… ARF OSS v3.3.9
63
  </span>
64
  <span style="padding: 8px 16px; background: #3b82f6; color: white; border-radius: 8px; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 6px; border: 1px solid #3b82f6;">
65
+ 🏒 Enterprise Execution
66
  </span>
67
  </div>
68
  """)
69
 
70
  # -----------------------------
71
+ # NEW: Observation Gate Renderer - CRITICAL PSYCHOLOGICAL FIX
72
+ # -----------------------------
73
+ def render_observation_gate(healing_intent: Dict[str, Any]) -> gr.HTML:
74
+ """
75
+ Render observation gate state as active restraint, not passive waiting.
76
+ Doctrinal: Make inaction an explicit, powerful decision.
77
+ """
78
+ deferral_reason = healing_intent.get("deferral_reason", "uncertainty_too_high_for_action")
79
+ frozen_until = healing_intent.get("decision_frozen_until", "")
80
+ confidence = healing_intent.get("confidence", 0.0)
81
+
82
+ # Parse timestamp for countdown
83
+ countdown_text = ""
84
+ if frozen_until:
85
+ try:
86
+ frozen_dt = datetime.datetime.fromisoformat(frozen_until.replace("Z", "+00:00"))
87
+ now = datetime.datetime.now(datetime.timezone.utc)
88
+ if frozen_dt.tzinfo is None:
89
+ frozen_dt = frozen_dt.replace(tzinfo=datetime.timezone.utc)
90
+ time_left = frozen_dt - now
91
+ minutes_left = max(0, int(time_left.total_seconds() / 60))
92
+ countdown_text = f"{minutes_left}m"
93
+ except:
94
+ countdown_text = "5m"
95
+
96
+ return gr.HTML(f"""
97
+ <div style="border: 3px solid #3b82f6; border-radius: 16px; padding: 25px; background: linear-gradient(135deg, #f0f9ff 0%, #ffffff 100%); margin-bottom: 20px;">
98
+ <div style="display: flex; align-items: center; gap: 15px; margin-bottom: 20px;">
99
+ <div style="font-size: 40px; color: #3b82f6;">⏳</div>
100
+ <div style="flex: 1;">
101
+ <h3 style="margin: 0 0 8px 0; font-size: 20px; color: #1e293b; font-weight: 700;">
102
+ Decision Intentionally Deferred
103
+ </h3>
104
+ <p style="margin: 0; font-size: 14px; color: #64748b;">
105
+ System state: <strong>observe_only</strong> β€’ Confidence: {confidence:.1%}
106
+ </p>
107
+ </div>
108
+ <div style="padding: 10px 20px; background: #dbeafe; color: #1e40af; border-radius: 25px; font-size: 14px; font-weight: bold;">
109
+ ACTIVE RESTRAINT
110
+ </div>
111
+ </div>
112
+
113
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
114
+ <div style="padding: 18px; background: #f8fafc; border-radius: 12px;">
115
+ <div style="font-size: 13px; color: #64748b; margin-bottom: 8px; font-weight: 600;">REASON FOR DEFERRAL</div>
116
+ <div style="font-size: 15px; color: #1e293b; font-weight: 500; padding: 12px; background: white; border-radius: 8px; border-left: 4px solid #3b82f6;">
117
+ {deferral_reason.replace('_', ' ').title()}
118
+ </div>
119
+ </div>
120
+
121
+ <div style="padding: 18px; background: #f8fafc; border-radius: 12px;">
122
+ <div style="font-size: 13px; color: #64748b; margin-bottom: 8px; font-weight: 600;">NEXT EVALUATION</div>
123
+ <div style="font-size: 15px; color: #1e293b; font-weight: 500; padding: 12px; background: white; border-radius: 8px; border-left: 4px solid #10b981;">
124
+ System re-evaluates in: <span style="font-size: 24px; font-weight: 700; color: #10b981;">{countdown_text}</span>
125
+ </div>
126
+ </div>
127
+ </div>
128
+
129
+ <div style="background: #f0fdf4; border-radius: 12px; padding: 20px; border: 2px solid #10b981;">
130
+ <div style="display: flex; align-items: flex-start; gap: 15px;">
131
+ <div style="font-size: 24px; color: #10b981;">🎯</div>
132
+ <div style="flex: 1;">
133
+ <div style="font-size: 16px; font-weight: 600; color: #065f46; margin-bottom: 8px;">
134
+ This is a System Choice, Not a Limitation
135
+ </div>
136
+ <div style="font-size: 14px; color: #047857; line-height: 1.6;">
137
+ The system is <strong>choosing not to act</strong> because uncertainty exceeds policy thresholds.
138
+ This restraint demonstrates operational maturityβ€”eagerness is a liability in production.
139
+ <br><br>
140
+ <em>"What you are seeing is not waiting. It is judgment under uncertainty."</em>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ <div style="margin-top: 20px; padding-top: 20px; border-top: 2px solid #e2e8f0;">
147
+ <div style="font-size: 14px; color: #64748b; font-weight: 600; margin-bottom: 10px;">PREVENTED ACTIONS (CONTRANDICATED)</div>
148
+ <div style="display: flex; flex-wrap: wrap; gap: 10px;">
149
+ <span style="padding: 8px 16px; background: #fee2e2; color: #7f1d1d; border-radius: 20px; font-size: 13px; font-weight: 500;">scale_during_retry_storm</span>
150
+ <span style="padding: 8px 16px; background: #fee2e2; color: #7f1d1d; border-radius: 20px; font-size: 13px; font-weight: 500;">add_capacity_during_amplification</span>
151
+ <span style="padding: 8px 16px; background: #fee2e2; color: #7f1d1d; border-radius: 20px; font-size: 13px; font-weight: 500;">any_action_during_high_uncertainty</span>
152
+ </div>
153
+ </div>
154
+ </div>
155
+ """)
156
+
157
+ # -----------------------------
158
+ # NEW: Historical Evidence Panel - RECALL DOMINANCE
159
+ # -----------------------------
160
+ def create_historical_evidence_panel(scenario_data: Dict[str, Any]) -> gr.HTML:
161
+ """
162
+ Create doctrinally compliant historical evidence panel.
163
+ Must be visually dominant with dates/environments.
164
+ """
165
+ # Extract from scenario or use defaults
166
+ historical_panel = scenario_data.get("historical_evidence_panel", {})
167
+
168
+ scaling_failures = historical_panel.get("scaling_first_failures", [])
169
+ dampening_successes = historical_panel.get("dampening_first_successes", [])
170
+
171
+ # Build failures HTML
172
+ failures_html = ""
173
+ for i, failure in enumerate(scaling_failures[:3]): # Show top 3
174
+ failures_html += f"""
175
+ <div style="border-left: 4px solid #ef4444; padding-left: 15px; margin-bottom: 15px;">
176
+ <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 5px;">
177
+ <div style="font-size: 14px; font-weight: 600; color: #1e293b;">{failure.get('date', 'Unknown')} β€’ {failure.get('environment', 'Unknown')}</div>
178
+ <div style="padding: 3px 10px; background: #fee2e2; color: #dc2626; border-radius: 12px; font-size: 11px; font-weight: bold;">FAILED</div>
179
+ </div>
180
+ <div style="font-size: 13px; color: #475569; margin-bottom: 5px;">
181
+ <strong>Action:</strong> {failure.get('action', 'Unknown')}
182
+ </div>
183
+ <div style="font-size: 13px; color: #dc2626; font-weight: 500; margin-bottom: 3px;">
184
+ <strong>Outcome:</strong> {failure.get('outcome', 'Unknown')}
185
+ </div>
186
+ <div style="font-size: 12px; color: #7f1d1d; font-style: italic; background: #fef2f2; padding: 8px; border-radius: 6px;">
187
+ {failure.get('lesson', 'No lesson captured')}
188
+ </div>
189
+ </div>
190
+ """
191
+
192
+ # Build successes HTML
193
+ successes_html = ""
194
+ for i, success in enumerate(dampening_successes[:3]): # Show top 3
195
+ successes_html += f"""
196
+ <div style="border-left: 4px solid #10b981; padding-left: 15px; margin-bottom: 15px;">
197
+ <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 5px;">
198
+ <div style="font-size: 14px; font-weight: 600; color: #1e293b;">{success.get('date', 'Unknown')} β€’ {success.get('environment', 'Unknown')}</div>
199
+ <div style="padding: 3px 10px; background: #dcfce7; color: #166534; border-radius: 12px; font-size: 11px; font-weight: bold;">SUCCESS</div>
200
+ </div>
201
+ <div style="font-size: 13px; color: #475569; margin-bottom: 5px;">
202
+ <strong>Action:</strong> {success.get('action', 'Unknown')}
203
+ </div>
204
+ <div style="font-size: 13px; color: #10b981; font-weight: 500; margin-bottom: 3px;">
205
+ <strong>Outcome:</strong> {success.get('outcome', 'Unknown')}
206
+ </div>
207
+ <div style="font-size: 12px; color: #065f46; font-style: italic; background: #f0fdf4; padding: 8px; border-radius: 6px;">
208
+ {success.get('lesson', 'No lesson captured')}
209
+ </div>
210
+ </div>
211
+ """
212
+
213
+ return gr.HTML(f"""
214
+ <div style="border: 3px solid #3b82f6; border-radius: 16px; padding: 25px; margin-bottom: 25px; background: linear-gradient(135deg, #f8fafc 0%, #ffffff 100%);">
215
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px;">
216
+ <div>
217
+ <h3 style="margin: 0 0 8px 0; font-size: 20px; color: #1e293b; font-weight: 700;">
218
+ 🧠 Historical Evidence (Why Sequencing Matters)
219
+ </h3>
220
+ <p style="margin: 0; font-size: 14px; color: #64748b;">
221
+ Real outcomes from similar incidentsβ€”this evidence dominates decision logic
222
+ </p>
223
+ </div>
224
+ <div style="padding: 8px 16px; background: #dbeafe; color: #1e40af; border-radius: 20px; font-size: 12px; font-weight: bold;">
225
+ RECALL DOMINANCE: POLICY OVER PREDICTION
226
+ </div>
227
+ </div>
228
+
229
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 25px; margin-bottom: 25px;">
230
+ <div>
231
+ <div style="font-size: 16px; font-weight: 600; color: #dc2626; margin-bottom: 15px; display: flex; align-items: center; gap: 8px;">
232
+ <span>β›”</span> Scaling-First Failures
233
+ </div>
234
+ {failures_html if failures_html else """
235
+ <div style="padding: 20px; background: #fef2f2; border-radius: 10px; text-align: center;">
236
+ <div style="font-size: 32px; color: #dc2626; margin-bottom: 10px;">πŸ“Š</div>
237
+ <div style="font-size: 14px; color: #7f1d1d;">No scaling failure evidence in memory</div>
238
+ </div>
239
+ """}
240
+ </div>
241
+
242
+ <div>
243
+ <div style="font-size: 16px; font-weight: 600; color: #10b981; margin-bottom: 15px; display: flex; align-items: center; gap: 8px;">
244
+ <span>βœ…</span> Dampening-First Successes
245
+ </div>
246
+ {successes_html if successes_html else """
247
+ <div style="padding: 20px; background: #f0fdf4; border-radius: 10px; text-align: center;">
248
+ <div style="font-size: 32px; color: #10b981; margin-bottom: 10px;">πŸ“Š</div>
249
+ <div style="font-size: 14px; color: #065f46;">No dampening success evidence in memory</div>
250
+ </div>
251
+ """}
252
+ </div>
253
+ </div>
254
+
255
+ <div style="background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border-radius: 12px; padding: 20px; border: 2px solid #0ea5e9;">
256
+ <div style="display: flex; align-items: flex-start; gap: 15px;">
257
+ <div style="font-size: 28px; color: #0ea5e9;">🎯</div>
258
+ <div style="flex: 1;">
259
+ <div style="font-size: 16px; font-weight: 600; color: #0369a1; margin-bottom: 8px;">
260
+ Doctrinal Principle: Memory Dominates Models
261
+ </div>
262
+ <div style="font-size: 14px; color: #0c4a6e; line-height: 1.6;">
263
+ The system prioritizes <strong>historical evidence over predictive confidence</strong>.
264
+ If scaling-first failed in similar conditions, scaling is contraindicated regardless of model confidence.
265
+ <br><br>
266
+ <em>"What happened is more important than what might happen."</em>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ </div>
271
+ </div>
272
+ """)
273
+
274
+ # -----------------------------
275
+ # Performance Metrics Function - DOCTRINAL METRICS
276
  # -----------------------------
277
  def update_performance_metrics(scenario_name: str, scenarios=INCIDENT_SCENARIOS) -> tuple:
278
  """
279
  Update performance metrics based on scenario
280
  Returns: (detection_time_html, mttr_html, auto_heal_html, savings_html)
281
+ Doctrinal: No red/green colors, use gradient colors instead of binary thresholds
 
 
 
 
 
 
282
  """
283
 
284
+ # Scenario-specific metrics mapping WITH GRADIENT COLORS
285
  metrics_config = {
 
286
  "Cache": {
287
+ "detection_time": ("45s", "89% faster", "linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)"),
288
+ "mttr": ("12m", "73% reduction", "linear-gradient(135deg, #10b981 0%, #047857 100%)"),
289
+ "auto_heal": ("82%", "5.4Γ— improvement", "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)"),
290
  "savings_multiplier": 0.85
291
  },
 
292
  "Database": {
293
+ "detection_time": ("38s", "91% faster", "linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)"),
294
+ "mttr": ("18m", "68% reduction", "linear-gradient(135deg, #10b981 0%, #047857 100%)"),
295
+ "auto_heal": ("74%", "4.8Γ— improvement", "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)"),
296
  "savings_multiplier": 0.82
297
  },
 
298
  "Kubernetes": {
299
+ "detection_time": ("52s", "87% faster", "linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)"),
300
+ "mttr": ("15m", "71% reduction", "linear-gradient(135deg, #10b981 0%, #047857 100%)"),
301
+ "auto_heal": ("79%", "5.1Γ— improvement", "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)"),
302
  "savings_multiplier": 0.83
303
  },
 
304
  "Network": {
305
+ "detection_time": ("28s", "93% faster", "linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)"),
306
+ "mttr": ("8m", "82% reduction", "linear-gradient(135deg, #10b981 0%, #047857 100%)"),
307
+ "auto_heal": ("89%", "6.2Γ— improvement", "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)"),
308
  "savings_multiplier": 0.88
309
  },
 
310
  "Storage": {
311
+ "detection_time": ("35s", "92% faster", "linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)"),
312
+ "mttr": ("22m", "65% reduction", "linear-gradient(135deg, #10b981 0%, #047857 100%)"),
313
+ "auto_heal": ("72%", "4.6Γ— improvement", "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)"),
314
  "savings_multiplier": 0.80
315
  },
 
316
  "Default": {
317
+ "detection_time": ("42s", "90% faster", "linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)"),
318
+ "mttr": ("14m", "70% reduction", "linear-gradient(135deg, #10b981 0%, #047857 100%)"),
319
+ "auto_heal": ("79%", "5.0Γ— improvement", "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)"),
320
  "savings_multiplier": 0.85
321
  }
322
  }
 
334
  # Get scenario data for savings calculation
335
  scenario_data = scenarios.get(scenario_name, {})
336
  business_impact = scenario_data.get("business_impact", {})
337
+ revenue_loss = business_impact.get('revenue_risk_per_hour', 8500) # Changed from 'revenue_loss_per_hour'
338
  savings_amount = int(revenue_loss * metrics["savings_multiplier"] / 1000)
339
 
340
+ # Create HTML for each metric card WITH GRADIENT BORDERS
341
  detection_time_html = f"""
342
+ <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px;
343
+ border-left: 4px solid; border-image: {metrics['detection_time'][2]}; border-image-slice: 1;">
344
  <div style="font-size: 28px; margin-bottom: 10px;">⏱️</div>
345
  <div>
346
  <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Detection Time</h4>
347
+ <p style="font-size: 28px; font-weight: bold; background: {metrics['detection_time'][2]}; -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 8px 0;">{metrics['detection_time'][0]}</p>
348
+ <p style="font-size: 12px; color: #64748b; margin: 0;">{metrics['detection_time'][1]} than baseline</p>
349
  </div>
350
  </div>
351
  """
352
 
353
  mttr_html = f"""
354
+ <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px;
355
+ border-left: 4px solid; border-image: {metrics['mttr'][2]}; border-image-slice: 1;">
356
  <div style="font-size: 28px; margin-bottom: 10px;">⚑</div>
357
  <div>
358
  <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Mean Time to Resolve</h4>
359
+ <p style="font-size: 28px; font-weight: bold; background: {metrics['mttr'][2]}; -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 8px 0;">{metrics['mttr'][0]}</p>
360
+ <p style="font-size: 12px; color: #64748b; margin: 0;">{metrics['mttr'][1]} than manual</p>
361
  </div>
362
  </div>
363
  """
364
 
365
  auto_heal_html = f"""
366
+ <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px;
367
+ border-left: 4px solid; border-image: {metrics['auto_heal'][2]}; border-image-slice: 1;">
368
+ <div style="font-size: 28px; margin-bottom: 10px;">πŸ›‘οΈ</div>
369
  <div>
370
  <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Auto-Heal Rate</h4>
371
+ <p style="font-size: 28px; font-weight: bold; background: {metrics['auto_heal'][2]}; -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 8px 0;">{metrics['auto_heal'][0]}</p>
372
+ <p style="font-size: 12px; color: #64748b; margin: 0;">{metrics['auto_heal'][1]}</p>
373
  </div>
374
  </div>
375
  """
376
 
377
  savings_html = f"""
378
+ <div style="border: 1px solid #e2e8f0; border-radius: 12px; padding: 18px; background: white; margin: 8px; text-align: center; flex: 1; min-width: 140px;
379
+ border-left: 4px solid; border-image: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); border-image-slice: 1;">
380
  <div style="font-size: 28px; margin-bottom: 10px;">πŸ’°</div>
381
  <div>
382
+ <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b; font-weight: 600;">Cost Avoided</h4>
383
+ <p style="font-size: 28px; font-weight: bold; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 8px 0;">${savings_amount:.1f}K</p>
384
  <p style="font-size: 12px; color: #64748b; margin: 0;">Per incident avoided</p>
385
  </div>
386
  </div>
 
390
  return detection_time_html, mttr_html, auto_heal_html, savings_html
391
 
392
  # -----------------------------
393
+ # Tab 1: Live Incident Demo - DOCTRINAL COMPLIANCE
394
  # -----------------------------
395
  def create_tab1_incident_demo(scenarios=INCIDENT_SCENARIOS, default_scenario="Cache Miss Storm") -> tuple:
396
  """
397
+ Create doctrinally compliant incident demo tab.
398
+ Doctrinal: Language discipline, sequencing display, no early "critical"
 
399
  """
400
 
401
  # Get the default scenario data
 
410
  scenario_dropdown = gr.Dropdown(
411
  choices=list(scenarios.keys()),
412
  value=default_scenario,
413
+ label="🎯 Select Variance Scenario",
414
+ info="Choose a production variance pattern to analyze",
415
  interactive=True,
416
  container=False
417
  )
418
 
419
+ # ============ HISTORICAL EVIDENCE PANEL FIRST (RECALL DOMINANCE) ============
420
+ historical_panel = create_historical_evidence_panel(default_scenario_data)
421
+
422
+ # Scenario Card with doctrinally compliant language
423
  scenario_card = gr.HTML(f"""
424
  <div style="border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px; background: white; box-shadow: 0 4px 12px rgba(0,0,0,0.05); margin-bottom: 20px;">
425
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid #f1f5f9;">
426
+ <h3 style="margin: 0; font-size: 18px; color: #1e293b;">πŸ“Š {default_scenario}</h3>
427
+ <span style="padding: 4px 12px; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); border-radius: 20px; font-size: 12px; font-weight: bold; color: white; text-transform: uppercase; letter-spacing: 0.5px;">{default_scenario_data.get('severity', 'HIGH_VARIANCE')}</span>
428
  </div>
429
  <div style="margin-top: 15px;">
430
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
 
432
  <span style="font-size: 14px; color: #1e293b; font-weight: 600;">{default_scenario_data.get('component', 'Unknown').replace('_', ' ').title()}</span>
433
  </div>
434
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
435
+ <span style="font-size: 13px; color: #64748b; font-weight: 500;">Users Affected:</span>
436
  <span style="font-size: 14px; color: #1e293b; font-weight: 600;">{metrics.get('affected_users', 'Unknown') if 'affected_users' in metrics else 'Unknown'}</span>
437
  </div>
438
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
439
  <span style="font-size: 13px; color: #64748b; font-weight: 500;">Revenue Risk:</span>
440
+ <span style="font-size: 14px; color: #f59e0b; font-weight: 700;">${business_impact.get('revenue_risk_per_hour', 0):,}/hour</span>
441
  </div>
442
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding: 4px 0;">
443
  <span style="font-size: 13px; color: #64748b; font-weight: 500;">Detection Time:</span>
444
+ <span style="font-size: 14px; color: #1e293b; font-weight: 600;">45 seconds (Policy System)</span>
445
  </div>
446
  <div style="display: flex; flex-wrap: wrap; gap: 6px; margin-top: 15px; padding-top: 12px; border-top: 1px solid #f1f5f9;">
447
  <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">{default_scenario_data.get('component', 'unknown').split('_')[0]}</span>
448
+ <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">variance</span>
449
  <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">production</span>
450
+ <span style="padding: 3px 8px; background: #f1f5f9; border-radius: 6px; font-size: 11px; color: #475569; font-weight: 500;">pattern</span>
451
  </div>
452
  </div>
453
  </div>
454
  """)
455
 
456
+ # Visualization section
457
  with gr.Row():
458
  with gr.Column(scale=1):
459
  telemetry_header = gr.Markdown("### πŸ“ˆ Live Telemetry")
 
460
  telemetry_viz = gr.Plot(
461
  label="",
462
  show_label=False,
 
471
  elem_id="impact_plot"
472
  )
473
 
474
+ # Middle Column: Process Workflow (NOT Agent Workflow)
475
  with gr.Column(scale=2, variant="panel") as middle_col:
476
+ # ============ OBSERVATION GATE PLACEHOLDER ============
477
+ observation_gate_placeholder = gr.HTML("""
478
+ <div style="text-align: center; padding: 30px; color: #64748b; background: #f8fafc; border-radius: 12px; margin-bottom: 20px;">
479
+ <div style="font-size: 48px; margin-bottom: 10px;">🎯</div>
480
+ <h4 style="margin: 0 0 10px 0;">System State</h4>
481
+ <p style="margin: 0;">Run analysis to see system's judgment under uncertainty</p>
482
+ </div>
483
+ """)
484
+
485
+ # ============ SEQUENCING VISUALIZATION ============
486
+ sequencing_header = gr.Markdown("### πŸ”„ Sequencing Logic: Dampening β†’ Concurrency β†’ Observe β†’ Scale")
487
+ sequencing_panel = gr.HTML("""
488
+ <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 20px; background: #f8fafc; margin-bottom: 20px;">
489
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
490
+ <h4 style="margin: 0; font-size: 16px; color: #1e293b; font-weight: 600;">Doctrinal Sequencing</h4>
491
+ <span style="padding: 4px 12px; background: #dbeafe; color: #1e40af; border-radius: 20px; font-size: 11px; font-weight: bold;">POLICY ENFORCED</span>
492
+ </div>
493
 
494
+ <div style="display: flex; justify-content: space-between; align-items: center; position: relative; margin-bottom: 25px;">
495
+ <div style="position: absolute; top: -10px; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, #3b82f6, #10b981, #8b5cf6, #f59e0b);"></div>
496
+
497
+ <div style="text-align: center; position: relative; flex: 1;">
498
+ <div style="width: 50px; height: 50px; background: #3b82f6; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-size: 20px; font-weight: bold;">1</div>
499
+ <div style="font-size: 13px; font-weight: 600; color: #1e293b;">Dampening</div>
500
+ <div style="font-size: 11px; color: #64748b;">Prevent amplification</div>
501
+ </div>
502
+
503
+ <div style="font-size: 20px; color: #94a3b8;">β†’</div>
504
+
505
+ <div style="text-align: center; position: relative; flex: 1;">
506
+ <div style="width: 50px; height: 50px; background: #10b981; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-size: 20px; font-weight: bold;">2</div>
507
+ <div style="font-size: 13px; font-weight: 600; color: #1e293b;">Concurrency Control</div>
508
+ <div style="font-size: 11px; color: #64748b;">Manage load</div>
509
+ </div>
510
+
511
+ <div style="font-size: 20px; color: #94a3b8;">β†’</div>
512
+
513
+ <div style="text-align: center; position: relative; flex: 1;">
514
+ <div style="width: 50px; height: 50px; background: #8b5cf6; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-size: 20px; font-weight: bold;">3</div>
515
+ <div style="font-size: 13px; font-weight: 600; color: #1e293b;">Observe</div>
516
+ <div style="font-size: 11px; color: #64748b;">Validate trends</div>
517
+ </div>
518
+
519
+ <div style="font-size: 20px; color: #94a3b8;">β†’</div>
520
+
521
+ <div style="text-align: center; position: relative; flex: 1;">
522
+ <div style="width: 50px; height: 50px; background: #f59e0b; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-size: 20px; font-weight: bold;">4</div>
523
+ <div style="font-size: 13px; font-weight: 600; color: #1e293b;">Scale</div>
524
+ <div style="font-size: 11px; color: #64748b;">Only if necessary</div>
525
+ </div>
526
+ </div>
527
+
528
+ <div style="padding: 15px; background: white; border-radius: 10px; border-left: 4px solid #3b82f6;">
529
+ <div style="font-size: 13px; color: #475569; font-weight: 500;">
530
+ <strong>Doctrinal Constraint:</strong> Scaling NEVER appears in same intent bundle as dampening.
531
+ System must observe stabilization before considering capacity increases.
532
+ </div>
533
+ </div>
534
+ </div>
535
+ """)
536
 
537
+ # Process Workflow Header (NOT Agent Workflow)
538
+ workflow_header = gr.Markdown("## πŸ”„ Policy Process Workflow")
539
+ workflow_subheader = gr.Markdown("### How the system transforms variance into policy execution")
540
 
541
+ # Process Status Cards (NOT Agent Status Cards)
542
  with gr.Row():
543
+ detection_process = gr.HTML("""
544
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 18px; background: #f8fafc; text-align: center; flex: 1; margin: 5px; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0.7;">
545
  <div style="font-size: 32px; margin-bottom: 10px; opacity: 0.5;">πŸ•΅οΈβ€β™‚οΈ</div>
546
  <div style="width: 100%;">
547
+ <h4 style="margin: 0 0 8px 0; font-size: 16px; color: #94a3b8;">Detection Process</h4>
548
+ <p style="font-size: 13px; color: #cbd5e1; margin-bottom: 12px; line-height: 1.4;">Click "Run Policy Analysis" to activate</p>
549
  <div style="display: flex; justify-content: space-around; margin-bottom: 12px;">
550
  <span style="font-size: 11px; padding: 3px 8px; background: rgba(255, 255, 255, 0.5); border-radius: 6px; color: #cbd5e1; font-weight: 500;">Status: Inactive</span>
551
  </div>
 
554
  </div>
555
  """)
556
 
557
+ recall_process = gr.HTML("""
558
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 18px; background: #f8fafc; text-align: center; flex: 1; margin: 5px; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0.7;">
559
  <div style="font-size: 32px; margin-bottom: 10px; opacity: 0.5;">🧠</div>
560
  <div style="width: 100%;">
561
+ <h4 style="margin: 0 0 8px 0; font-size: 16px; color: #94a3b8;">Recall Process</h4>
562
+ <p style="font-size: 13px; color: #cbd5e1; margin-bottom: 12px; line-height: 1.4;">Click "Run Policy Analysis" to activate</p>
563
  <div style="display: flex; justify-content: space-around; margin-bottom: 12px;">
564
  <span style="font-size: 11px; padding: 3px 8px; background: rgba(255, 255, 255, 0.5); border-radius: 6px; color: #cbd5e1; font-weight: 500;">Status: Inactive</span>
565
  </div>
 
568
  </div>
569
  """)
570
 
571
+ decision_process = gr.HTML("""
572
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 18px; background: #f8fafc; text-align: center; flex: 1; margin: 5px; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0.7;">
573
  <div style="font-size: 32px; margin-bottom: 10px; opacity: 0.5;">🎯</div>
574
  <div style="width: 100%;">
575
+ <h4 style="margin: 0 0 8px 0; font-size: 16px; color: #94a3b8;">Decision Process</h4>
576
+ <p style="font-size: 13px; color: #cbd5e1; margin-bottom: 12px; line-height: 1.4;">Click "Run Policy Analysis" to activate</p>
577
  <div style="display: flex; justify-content: space-around; margin-bottom: 12px;">
578
  <span style="font-size: 11px; padding: 3px 8px; background: rgba(255, 255, 255, 0.5); border-radius: 6px; color: #cbd5e1; font-weight: 500;">Status: Inactive</span>
579
  </div>
 
582
  </div>
583
  """)
584
 
585
+ # Mode Selection & Safety Controls
586
+ with gr.Row():
587
+ with gr.Column(scale=1):
588
+ approval_toggle = gr.CheckboxGroup(
589
+ choices=["πŸ‘€ Require Human Approval"],
590
+ label="Safety Controls",
591
+ value=[],
592
+ info="Toggle human oversight"
593
+ )
594
+
595
+ with gr.Column(scale=2):
596
+ mcp_mode = gr.Radio(
597
+ choices=["πŸ›‘οΈ Advisory (OSS Only)", "πŸ‘₯ Approval", "⚑ Autonomous"],
598
+ value="πŸ›‘οΈ Advisory (OSS Only)",
599
+ label="Policy Safety Mode",
600
+ info="Control execution safety level",
601
+ interactive=True
602
+ )
603
+
604
  # OSS vs Enterprise Boundary Visualization
605
+ boundary_header = gr.Markdown("### 🎭 Policy vs Execution: The Safety Boundary")
606
 
607
  with gr.Row():
608
  oss_section = gr.HTML("""
609
  <div style="padding: 20px; border-radius: 14px; margin-bottom: 15px; flex: 1; min-height: 320px; background: #f0f9ff; border: 2px solid #0ea5e9;">
610
  <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid rgba(0, 0, 0, 0.1);">
611
  <div style="font-size: 28px;">πŸ†“</div>
612
+ <h3 style="margin: 0; font-size: 20px; color: #1e293b; flex: 1;">Policy Edition</h3>
613
  <span style="padding: 4px 10px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; font-size: 11px; font-weight: bold; color: #475569;">Apache 2.0</span>
614
  </div>
615
  <div style="margin-bottom: 20px; padding: 12px; background: rgba(255, 255, 255, 0.7); border-radius: 10px;">
 
617
  </div>
618
  <div style="background: white; border-radius: 12px; padding: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.05);">
619
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #f1f5f9;">
620
+ <h4 style="margin: 0; font-size: 16px; color: #1e293b;">πŸ“ HealingIntent Created</h4>
621
  <span style="padding: 4px 10px; background: #dbeafe; color: #1d4ed8; border-radius: 6px; font-size: 12px; font-weight: bold;">94% confidence</span>
622
  </div>
623
  <div>
624
+ <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Action:</strong> Implement request coalescing with exponential backoff</p>
625
+ <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Pattern Match:</strong> Similar incident resolved with dampening (87% success rate)</p>
626
+ <p style="margin: 8px 0; font-size= 14px; color: #475569;"><strong>Contraindications:</strong> βœ… Checked (retry amplification detected)</p>
627
+ <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Sequencing Rule:</strong> dampening_first_then_observe_then_optional_scale</p>
628
  </div>
629
  <div style="margin-top: 20px; text-align: center;">
630
  <div style="height: 2px; background: linear-gradient(90deg, transparent, #3b82f6, transparent); margin: 8px 0;"></div>
 
639
  <div style="padding: 20px; border-radius: 14px; margin-bottom: 15px; flex: 1; min-height: 320px; background: #f0fdf4; border: 2px solid #10b981;">
640
  <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid rgba(0, 0, 0, 0.1);">
641
  <div style="font-size: 28px;">πŸ’°</div>
642
+ <h3 style="margin: 0; font-size: 20px; color: #1e293b; flex: 1;">Execution Edition</h3>
643
  <span style="padding: 4px 10px; background: rgba(255, 255, 255, 0.9); border-radius: 8px; font-size: 11px; font-weight: bold; color: #475569;">Commercial</span>
644
  </div>
645
  <div style="margin-bottom: 20px; padding: 12px; background: rgba(255, 255, 255, 0.7); border-radius: 10px;">
 
653
  <div>
654
  <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Mode:</strong> Autonomous (Requires Enterprise license)</p>
655
  <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Expected Recovery:</strong> 12 minutes (vs 45 min manual)</p>
656
+ <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Cost Avoided:</strong> <span style="color: #10b981; font-weight: 700;">$6,375</span></p>
657
  <p style="margin: 8px 0; font-size= 14px; color: #475569;"><strong>Users Protected:</strong> 45,000 β†’ 0 impacted</p>
658
  </div>
659
  <div style="margin-top: 20px; text-align: center;">
 
669
  with gr.Row():
670
  with gr.Column(scale=1):
671
  oss_btn = gr.Button(
672
+ "πŸ†“ Run Policy Analysis",
673
  variant="secondary",
674
  size="lg"
675
  )
676
+ oss_info = gr.Markdown("*Free, policy-only analysis*")
677
 
678
  with gr.Column(scale=1):
679
  enterprise_btn = gr.Button(
 
690
  show_label=False,
691
  elem_id="timeline_plot"
692
  )
 
 
 
 
 
 
 
 
 
 
 
693
 
694
  # Right Column: Results & Metrics
695
  with gr.Column(scale=1, variant="panel") as right_col:
696
  # Real-time Metrics Dashboard
697
  metrics_header = gr.Markdown("## πŸ“Š Performance Metrics")
698
 
699
+ # Metric Cards Grid - CALL update_performance_metrics function
700
+ detection_time = gr.HTML()
701
+ mttr = gr.HTML()
702
+ auto_heal = gr.HTML()
703
+ savings = gr.HTML()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
704
 
705
  # Results Display Areas
706
+ oss_results_header = gr.Markdown("### πŸ†“ Policy Analysis Results")
707
  oss_results_display = gr.JSON(
708
  label="",
709
  value={
710
  "status": "Analysis Pending",
711
+ "processes": ["Detection", "Recall", "Decision"],
712
  "mode": "Advisory Only",
713
+ "action": "Generate Formal HealingIntent"
714
  },
715
  height=200
716
  )
717
 
718
+ enterprise_results_header = gr.Markdown("### πŸ’° Execution Results")
719
  enterprise_results_display = gr.JSON(
720
  label="",
721
  value={
 
727
  height=200
728
  )
729
 
730
+ # Approval Status
731
  approval_display = gr.HTML("""
732
  <div style="border: 2px solid #e2e8f0; border-radius: 14px; padding: 20px; background: white; margin-top: 20px;">
733
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; padding-bottom: 12px; border-bottom: 2px solid #f1f5f9;">
 
735
  <span style="padding: 4px 12px; background: #10b981; color: white; border-radius: 8px; font-size: 12px; font-weight: bold; text-transform: uppercase;">Not Required</span>
736
  </div>
737
  <div style="margin-top: 15px;">
738
+ <p style="margin: 8px 0; font-size: 14px; color: #475569;"><strong>Current Mode:</strong> Advisory (Policy Only)</p>
739
  <p style="margin: 8px 0; font-size: 14px; color: #475569; font-style: italic;">Switch to "Approval" mode to enable human-in-the-loop workflows</p>
740
  <div style="display: flex; flex-direction: column; gap: 10px; margin-top: 20px;">
741
+ <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">1. System generates formal HealingIntent</div>
742
+ <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">2. Human reviews & approves contraindications</div>
743
+ <div style="padding: 12px; background: #f8fafc; border-radius: 10px; border-left: 4px solid #3b82f6; font-size: 14px; color: #475569; font-weight: 500;">3. System executes with sequencing constraints</div>
744
  </div>
745
  </div>
746
  </div>
 
748
 
749
  # Demo Actions
750
  demo_btn = gr.Button(
751
+ "▢️ Run Complete Walkthrough",
752
  variant="secondary",
753
  size="lg"
754
  )
755
+ demo_info = gr.Markdown("*Experience the full workflow from detection to resolution*")
756
 
757
  return (
758
  # Left column returns
759
+ scenario_dropdown, historical_panel, scenario_card, telemetry_viz, impact_viz,
760
+ # Middle column returns
761
+ observation_gate_placeholder, sequencing_panel, workflow_header, detection_process,
762
+ recall_process, decision_process, oss_section, enterprise_section, oss_btn, enterprise_btn,
763
+ approval_toggle, mcp_mode, timeline_viz,
764
  # Right column returns
765
  detection_time, mttr, auto_heal, savings,
766
  oss_results_display, enterprise_results_display, approval_display, demo_btn
767
  )
768
 
769
+ # -----------------------------
770
+ # NEW: Create Realism Panel (Updated for doctrinal compliance)
771
+ # -----------------------------
772
+ def create_realism_panel(scenario_data: Dict, scenario_name: str) -> gr.HTML:
773
+ """
774
+ Create doctrinally compliant realism panel.
775
+ Updated to show formal HealingIntent fields and sequencing logic.
776
+ """
777
+ ranked_actions = scenario_data.get("ranked_actions", [])
778
+
779
+ # Build ranked actions HTML with formal HealingIntent fields
780
+ actions_html = ""
781
+ for action in ranked_actions:
782
+ category = action.get("category", "unknown")
783
+ category_color = {
784
+ "dampening": "#3b82f6",
785
+ "concurrency_control": "#10b981",
786
+ "observation": "#8b5cf6",
787
+ "scaling": "#f59e0b"
788
+ }.get(category, "#64748b")
789
+
790
+ rank_color = "#3b82f6" if action["rank"] == 1 else "#f59e0b" if action["rank"] == 2 else "#64748b"
791
+ status = "βœ… RECOMMENDED" if action["rank"] == 1 else "🟑 SECONDARY" if action["rank"] == 2 else "πŸ”΄ CONTRAINDICATED"
792
+
793
+ # Formal HealingIntent fields
794
+ preconditions_html = ""
795
+ if action.get("preconditions"):
796
+ preconditions_html = f"""
797
+ <div style="margin-top: 10px; padding: 10px; background: #f8fafc; border-radius: 8px; border-left: 3px solid #3b82f6;">
798
+ <div style="font-size: 12px; color: #475569; font-weight: 600; margin-bottom: 5px;">Preconditions:</div>
799
+ {"".join([f'<div style="font-size: 11px; color: #64748b; margin-bottom: 3px;">β€’ {pre}</div>' for pre in action["preconditions"]])}
800
+ </div>
801
+ """
802
+
803
+ contraindications_html = ""
804
+ if action.get("contraindicated_actions"):
805
+ contraindications_html = f"""
806
+ <div style="margin-top: 10px; padding: 10px; background: #fef2f2; border-radius: 8px; border-left: 3px solid #ef4444;">
807
+ <div style="font-size: 12px; color: #7f1d1d; font-weight: 600; margin-bottom: 5px;">Contraindicated Actions:</div>
808
+ {"".join([f'<div style="font-size: 11px; color: #b91c1c; margin-bottom: 3px;">β›” {contra}</div>' for contra in action["contraindicated_actions"]])}
809
+ </div>
810
+ """
811
+
812
+ reversibility_html = ""
813
+ if action.get("reversibility_statement"):
814
+ reversibility_html = f"""
815
+ <div style="margin-top: 10px; padding: 10px; background: #f0fdf4; border-radius: 8px; border-left: 3px solid #10b981;">
816
+ <div style="font-size: 12px; color: #065f46; font-weight: 600; margin-bottom: 5px;">Reversibility Statement:</div>
817
+ <div style="font-size: 11px; color: #047857;">{action["reversibility_statement"]}</div>
818
+ </div>
819
+ """
820
+
821
+ historical_evidence_html = ""
822
+ if action.get("historical_evidence"):
823
+ historical_evidence_html = f"""
824
+ <div style="margin-top: 10px; padding: 10px; background: #fef3c7; border-radius: 8px; border-left: 3px solid #f59e0b;">
825
+ <div style="font-size: 12px; color: #92400e; font-weight: 600; margin-bottom: 5px;">Historical Evidence:</div>
826
+ {"".join([f'<div style="font-size: 11px; color: #b45309; margin-bottom: 3px;">πŸ“Š {evidence}</div>' for evidence in action["historical_evidence"]])}
827
+ </div>
828
+ """
829
+
830
+ actions_html += f"""
831
+ <div style="border: 2px solid {category_color}; border-radius: 12px; padding: 16px;
832
+ background: {category_color}10; margin-bottom: 12px;">
833
+ <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px;">
834
+ <div style="flex: 1;">
835
+ <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 5px;">
836
+ <div style="width: 24px; height: 24px; background: {category_color};
837
+ color: white; border-radius: 50%; display: flex; align-items: center;
838
+ justify-content: center; font-size: 12px; font-weight: bold;">
839
+ {action['rank']}
840
+ </div>
841
+ <span style="font-size: 14px; font-weight: 600; color: #1e293b;">
842
+ {status} β€’ {action.get('confidence', 0)}% confidence
843
+ </span>
844
+ <span style="padding: 3px 8px; background: {category_color}30; color: {category_color}; border-radius: 12px; font-size: 11px; font-weight: bold;">
845
+ {category.upper().replace('_', ' ')}
846
+ </span>
847
+ </div>
848
+ <p style="font-size: 14px; color: #475569; margin: 8px 0; font-weight: 500;">
849
+ {action.get('action', 'No action specified')}
850
+ </p>
851
+ </div>
852
+ <div style="padding: 6px 12px; background: {category_color}20; border-radius: 20px;
853
+ font-size: 12px; font-weight: bold; color: {category_color};">
854
+ {action.get('confidence', 0)}%
855
+ </div>
856
+ </div>
857
+
858
+ {preconditions_html}
859
+ {contraindications_html}
860
+ {reversibility_html}
861
+ {historical_evidence_html}
862
+
863
+ <div style="margin-top: 10px; font-size: 12px; color: #64748b;">
864
+ <strong>Sequencing:</strong> {action.get('category', 'unknown').replace('_', ' ')} β€’ {action.get('constraints', ['No constraints'])[0]}
865
+ </div>
866
+ </div>
867
+ """
868
+
869
+ # Combine all panels
870
+ full_html = f"""
871
+ <div style="border: 2px solid #3b82f6; border-radius: 16px; padding: 25px;
872
+ background: linear-gradient(135deg, #f0f9ff 0%, #ffffff 100%); margin-top: 20px;">
873
+
874
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
875
+ <div>
876
+ <h3 style="margin: 0 0 8px 0; font-size: 18px; color: #1e293b; font-weight: 700;">
877
+ 🎯 Formal HealingIntent Sequence
878
+ </h3>
879
+ <p style="margin: 0; font-size: 13px; color: #64748b;">
880
+ Policy-generated intents with preconditions, contraindications, and reversibility statements
881
+ </p>
882
+ </div>
883
+ <div style="padding: 8px 16px; background: #dbeafe; color: #1e40af;
884
+ border-radius: 20px; font-size: 12px; font-weight: bold;">
885
+ DOCTRINAL COMPLIANCE v3.3.9+
886
+ </div>
887
+ </div>
888
+
889
+ {actions_html if actions_html else '<div style="text-align: center; padding: 30px; color: #64748b;">No ranked actions available</div>'}
890
+
891
+ <!-- Doctrinal Sequencing Summary -->
892
+ <div style="margin-top: 25px; padding-top: 20px; border-top: 2px solid #e2e8f0;">
893
+ <div style="font-size: 15px; font-weight: 600; color: #1e293b; margin-bottom: 15px;">
894
+ πŸ”„ Doctrinal Sequencing Enforcement
895
+ </div>
896
+ <div style="background: #f8fafc; border-radius: 12px; padding: 20px;">
897
+ <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; text-align: center;">
898
+ <div>
899
+ <div style="width: 40px; height: 40px; background: #3b82f6; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-weight: bold;">1</div>
900
+ <div style="font-size: 12px; font-weight: 600; color: #1e293b;">Dampening</div>
901
+ <div style="font-size: 10px; color: #64748b;">First in sequence</div>
902
+ </div>
903
+ <div>
904
+ <div style="width: 40px; height: 40px; background: #10b981; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-weight: bold;">2</div>
905
+ <div style="font-size: 12px; font-weight: 600; color: #1e293b;">Concurrency</div>
906
+ <div style="font-size: 10px; color: #64748b;">Then control</div>
907
+ </div>
908
+ <div>
909
+ <div style="width: 40px; height: 40px; background: #8b5cf6; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-weight: bold;">3</div>
910
+ <div style="font-size: 12px; font-weight: 600; color: #1e293b;">Observe</div>
911
+ <div style="font-size: 10px; color: #64748b;">Then validate</div>
912
+ </div>
913
+ <div>
914
+ <div style="width: 40px; height: 40px; background: #f59e0b; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-weight: bold;">4</div>
915
+ <div style="font-size: 12px; font-weight: 600; color: #1e293b;">Scale</div>
916
+ <div style="font-size: 10px; color: #64748b;">Only if necessary</div>
917
+ </div>
918
+ </div>
919
+ <div style="margin-top: 15px; padding: 12px; background: white; border-radius: 8px; border-left: 4px solid #3b82f6;">
920
+ <div style="font-size: 13px; color: #475569; font-weight: 500;">
921
+ <strong>Doctrinal Constraint:</strong> Scaling actions have lower confidence than dampening actions and appear last.
922
+ If retry amplification is detected, scaling is contraindicated entirely.
923
+ </div>
924
+ </div>
925
+ </div>
926
+ </div>
927
+ </div>
928
+ """
929
+
930
+ return gr.HTML(full_html)
931
+
932
  # -----------------------------
933
  # Tab 2: Business ROI - Updated
934
  # -----------------------------