diff --git a/api/blade-actions-surfaced.json b/api/blade-actions-surfaced.json
index f44b1e33b..efc6e2b0e 100644
--- a/api/blade-actions-surfaced.json
+++ b/api/blade-actions-surfaced.json
@@ -1,15 +1,15 @@
{
- "generated_at": "2026-04-19T16:00:01.728973",
+ "generated_at": "2026-04-19T16:05:01.406881",
"stats": {
- "total": 438,
- "pending": 837,
+ "total": 439,
+ "pending": 839,
"kaouther_surfaced": 29,
"chrome_surfaced": 10,
"notif_only_done": 0,
"autofix_archived": 0,
"cerebras_archived": 0,
"older_3d_archived": 0,
- "unknown": 399,
+ "unknown": 400,
"errors": 0
},
"actions": [
diff --git a/api/blade-tasks/task_20260419140501_63879c.json b/api/blade-tasks/task_20260419140501_63879c.json
new file mode 100644
index 000000000..d097e5e30
--- /dev/null
+++ b/api/blade-tasks/task_20260419140501_63879c.json
@@ -0,0 +1,11 @@
+{
+ "id": "task_20260419140501_63879c",
+ "name": "Blade self-heal 16:05",
+ "type": "powershell",
+ "command": "\n# Blade self-heal\nWrite-Host \"Self-heal triggered $(Get-Date)\"\n$agentProc = Get-Process powershell | Where-Object { $_.CommandLine -match 'sentinel-agent' }\nif (!$agentProc) {\n Write-Host \"Agent not running, starting...\"\n Start-Process powershell -ArgumentList \"-ExecutionPolicy\",\"Bypass\",\"-File\",\"C:\\ProgramData\\WEVAL\\sentinel-agent.ps1\" -WindowStyle Hidden\n}\n# Clear stale tasks > 3 days locally\n$cutoff = (Get-Date).AddDays(-3)\nGet-ChildItem \"C:\\ProgramData\\WEVAL\\tasks\\*.json\" -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt $cutoff } | Move-Item -Destination \"C:\\ProgramData\\WEVAL\\tasks\\archived\\\" -Force -ErrorAction SilentlyContinue\nWrite-Host \"Self-heal complete\"\n",
+ "cmd": "\n# Blade self-heal\nWrite-Host \"Self-heal triggered $(Get-Date)\"\n$agentProc = Get-Process powershell | Where-Object { $_.CommandLine -match 'sentinel-agent' }\nif (!$agentProc) {\n Write-Host \"Agent not running, starting...\"\n Start-Process powershell -ArgumentList \"-ExecutionPolicy\",\"Bypass\",\"-File\",\"C:\\ProgramData\\WEVAL\\sentinel-agent.ps1\" -WindowStyle Hidden\n}\n# Clear stale tasks > 3 days locally\n$cutoff = (Get-Date).AddDays(-3)\nGet-ChildItem \"C:\\ProgramData\\WEVAL\\tasks\\*.json\" -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt $cutoff } | Move-Item -Destination \"C:\\ProgramData\\WEVAL\\tasks\\archived\\\" -Force -ErrorAction SilentlyContinue\nWrite-Host \"Self-heal complete\"\n",
+ "priority": "high",
+ "status": "pending",
+ "created": "2026-04-19T14:05:01+00:00",
+ "created_by": "blade-control-ui"
+}
\ No newline at end of file
diff --git a/api/em-kpi-cache.json b/api/em-kpi-cache.json
index dc8b9473b..aada94287 100644
--- a/api/em-kpi-cache.json
+++ b/api/em-kpi-cache.json
@@ -1,281 +1,7 @@
-{
- "ts": "2026-04-19T14:00:01+00:00",
- "server": "s204",
- "s204": {
- "load": 0.38,
- "uptime": "2026-04-14 11:51:24",
- "ram_total_mb": 31335,
- "ram_used_mb": 7086,
- "ram_free_mb": 24249,
- "disk_total": "150G",
- "disk_used": "121G",
- "disk_free": "24G",
- "disk_pct": "84%",
- "fpm_workers": 98,
- "docker_containers": 19,
- "cpu_cores": 8
- },
- "s95": {
- "load": 1.07,
- "disk_pct": "89%",
- "status": "UP",
- "ram_total_mb": 15610,
- "ram_free_mb": 11539
- },
- "pmta": [
- {
- "name": "SER6",
- "ip": "110.239.84.121",
- "status": "DOWN"
- },
- {
- "name": "SER7",
- "ip": "110.239.65.64",
- "status": "DOWN"
- },
- {
- "name": "SER8",
- "ip": "182.160.55.107",
- "status": "DOWN"
- },
- {
- "name": "SER9",
- "ip": "110.239.86.68",
- "status": "DOWN"
- }
- ],
- "assets": {
- "html_pages": 248,
- "php_apis": 648,
- "wiki_entries": 1604,
- "vault_doctrines": 58,
- "vault_sessions": 15,
- "vault_decisions": 12
- },
- "tools": {
- "total": 619,
- "registry_version": "?"
- },
- "sovereign": {
- "status": "UP",
- "providers": [
- "Cerebras-fast",
- "Cerebras-think",
- "Groq",
- "Cloudflare-AI",
- "Gemini",
- "SambaNova",
- "NVIDIA-NIM",
- "Mistral",
- "Groq-OSS",
- "HF-Space",
- "HF-Router",
- "OpenRouter",
- "GitHub-Models"
- ],
- "active": 13,
- "total": 13,
- "primary": "Cerebras-fast",
- "cost": "0€"
- },
- "ethica": {
- "total_hcps": 156714,
- "with_email": 110336,
- "with_phone": 150477,
- "gap_email": 46378,
- "pct_email": 70.4,
- "pct_phone": 96,
- "by_country": [
- {
- "country": "DZ",
- "hcps": 117327,
- "with_email": 78275,
- "with_tel": 114729,
- "pct_email": 66.7,
- "pct_tel": 97.8
- },
- {
- "country": "MA",
- "hcps": 19716,
- "with_email": 15059,
- "with_tel": 18730,
- "pct_email": 76.4,
- "pct_tel": 95
- },
- {
- "country": "TN",
- "hcps": 17792,
- "with_email": 15123,
- "with_tel": 17018,
- "pct_email": 85,
- "pct_tel": 95.6
- },
- {
- "country": "INTL",
- "hcps": 1879,
- "with_email": 1879,
- "with_tel": 0,
- "pct_email": 100,
- "pct_tel": 0
- }
- ]
- },
- "docker": [
- {
- "name": "loki",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "listmonk",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "plausible-plausible-1",
- "status": "Up 47 hours",
- "ports": ""
- },
- {
- "name": "plausible-plausible-db-1",
- "status": "Up 47 hours",
- "ports": ""
- },
- {
- "name": "plausible-plausible-events-db-1",
- "status": "Up 47 hours",
- "ports": ""
- },
- {
- "name": "n8n-docker-n8n-1",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "mattermost-docker-mm-db-1",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "mattermost-docker-mattermost-1",
- "status": "Up 3 days (healthy)",
- "ports": ""
- },
- {
- "name": "twenty",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "twenty-redis",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "langfuse",
- "status": "Up 3 days",
- "ports": ""
- },
- {
- "name": "redis-weval",
- "status": "Up 5 days",
- "ports": ""
- },
- {
- "name": "gitea",
- "status": "Up 5 days",
- "ports": ""
- },
- {
- "name": "node-exporter",
- "status": "Up 5 days",
- "ports": ""
- },
- {
- "name": "prometheus",
- "status": "Up 5 days",
- "ports": ""
- },
- {
- "name": "searxng",
- "status": "Up 5 days",
- "ports": ""
- },
- {
- "name": "uptime-kuma",
- "status": "Up 5 days (healthy)",
- "ports": ""
- },
- {
- "name": "vaultwarden",
- "status": "Up 5 days (healthy)",
- "ports": ""
- },
- {
- "name": "qdrant",
- "status": "Up 5 days",
- "ports": ""
- }
- ],
- "crons": {
- "active": 15
- },
- "git": {
- "head": "50508b6a8 auto-commit via WEVIA vault_git intent 2026-04-19T14:00:07+00:00",
- "dirty": 0,
- "status": "CLEAN"
- },
- "nonreg": {
- "total": 153,
- "passed": 153,
- "score": "100%"
- },
- "services": [
- {
- "name": "DeerFlow",
- "port": 3002,
- "status": "UP"
- },
- {
- "name": "DeerFlow API",
- "port": 8001,
- "status": "UP"
- },
- {
- "name": "Qdrant",
- "port": 6333,
- "status": "UP"
- },
- {
- "name": "Ollama",
- "port": 11434,
- "status": "UP"
- },
- {
- "name": "Redis",
- "port": 6379,
- "status": "UP"
- },
- {
- "name": "Sovereign",
- "port": 4000,
- "status": "UP"
- },
- {
- "name": "SearXNG",
- "port": 8080,
- "status": "UP"
- }
- ],
- "whisper": {
- "binary": "COMPILED",
- "model": "142MB"
- },
- "grand_total": 3196,
- "health": {
- "score": 6,
- "max": 6,
- "pct": 100
- },
- "elapsed_ms": 11717
-}
\ No newline at end of file
+
+
500 Internal Server Error
+
+500 Internal Server Error
+
nginx/1.24.0 (Ubuntu)
+
+
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/01-wevia-master-loaded.png b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/01-wevia-master-loaded.png
new file mode 100644
index 000000000..2fd94238c
Binary files /dev/null and b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/01-wevia-master-loaded.png differ
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/99-final.png b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/99-final.png
new file mode 100644
index 000000000..2fd94238c
Binary files /dev/null and b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/99-final.png differ
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/df36b4289d4fbe0311a2e4e86eb1739c.webm b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/df36b4289d4fbe0311a2e4e86eb1739c.webm
new file mode 100644
index 000000000..9f40608fc
Binary files /dev/null and b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/df36b4289d4fbe0311a2e4e86eb1739c.webm differ
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/results.json b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/results.json
new file mode 100644
index 000000000..91f6b8d1c
--- /dev/null
+++ b/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50/results.json
@@ -0,0 +1,69 @@
+{
+ "start": "2026-04-19T16:02:50",
+ "tests": [
+ {
+ "name": "wevia-master-load",
+ "status": "OK",
+ "title": "WEVAL — Login"
+ },
+ {
+ "name": "sse-multi-agent",
+ "status": "PARTIAL",
+ "total_agents": 0,
+ "unique": 0,
+ "v76_found": 0,
+ "http_status": 200,
+ "body_size": 842
+ },
+ {
+ "name": "get-/api/wevia-sse-v76-agents-ext.php",
+ "http": 200,
+ "size": 0
+ },
+ {
+ "name": "get-/api/v76-scripts/avatar-audit.sh",
+ "http": 200,
+ "size": 348
+ },
+ {
+ "name": "six-sigma-live",
+ "status": "OK",
+ "dpmo": 0,
+ "sigma": 6,
+ "status_sigma": "ON_TARGET",
+ "dmaic": "CONTROL",
+ "autonomy_pct": 63.5
+ },
+ {
+ "name": "truth-registry",
+ "status": "OK",
+ "agents": 270,
+ "doctrines": 19,
+ "dashboards": 93,
+ "brains": 25
+ },
+ {
+ "name": "v82-tips",
+ "status": "OK",
+ "total_categories": 8,
+ "total_tips": 41
+ }
+ ],
+ "v76_agents_visible": {
+ "avatar_audit": false,
+ "selenium_check": false,
+ "playwright_check": false,
+ "registry_status": false,
+ "six_sigma_live": false,
+ "chrome_blade": false,
+ "cyber_tips": false,
+ "autonomy_score": false
+ },
+ "video_path": "df36b4289d4fbe0311a2e4e86eb1739c.webm",
+ "screenshots": [
+ "01-wevia-master-loaded.png",
+ "99-final.png"
+ ],
+ "end": "2026-04-19T16:02:55",
+ "out_dir": "/var/www/html/api/playwright-results/v76-multi-agent-2026-04-19T16-02-50"
+}
\ No newline at end of file
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/01-wevia-master-loaded.png b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/01-wevia-master-loaded.png
new file mode 100644
index 000000000..2fd94238c
Binary files /dev/null and b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/01-wevia-master-loaded.png differ
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/99-final.png b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/99-final.png
new file mode 100644
index 000000000..2fd94238c
Binary files /dev/null and b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/99-final.png differ
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/d34e156716b4587a55446b0b86e92944.webm b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/d34e156716b4587a55446b0b86e92944.webm
new file mode 100644
index 000000000..edcde528f
Binary files /dev/null and b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/d34e156716b4587a55446b0b86e92944.webm differ
diff --git a/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/results.json b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/results.json
new file mode 100644
index 000000000..366123e52
--- /dev/null
+++ b/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45/results.json
@@ -0,0 +1,69 @@
+{
+ "start": "2026-04-19T16:04:45",
+ "tests": [
+ {
+ "name": "wevia-master-load",
+ "status": "OK",
+ "title": "WEVAL — Login"
+ },
+ {
+ "name": "sse-multi-agent",
+ "status": "OK",
+ "total_agents": 32,
+ "unique": 32,
+ "v76_found": 8,
+ "http_status": 200,
+ "body_size": 14312
+ },
+ {
+ "name": "get-/api/wevia-sse-v76-agents-ext.php",
+ "http": 200,
+ "size": 0
+ },
+ {
+ "name": "get-/api/v76-scripts/avatar-audit.sh",
+ "http": 200,
+ "size": 348
+ },
+ {
+ "name": "six-sigma-live",
+ "status": "OK",
+ "dpmo": 0,
+ "sigma": 6,
+ "status_sigma": "ON_TARGET",
+ "dmaic": "CONTROL",
+ "autonomy_pct": 63.5
+ },
+ {
+ "name": "truth-registry",
+ "status": "OK",
+ "agents": 270,
+ "doctrines": 19,
+ "dashboards": 93,
+ "brains": 25
+ },
+ {
+ "name": "v82-tips",
+ "status": "OK",
+ "total_categories": 8,
+ "total_tips": 41
+ }
+ ],
+ "v76_agents_visible": {
+ "avatar_audit": true,
+ "selenium_check": true,
+ "playwright_check": true,
+ "registry_status": true,
+ "six_sigma_live": true,
+ "chrome_blade": true,
+ "cyber_tips": true,
+ "autonomy_score": true
+ },
+ "video_path": "d34e156716b4587a55446b0b86e92944.webm",
+ "screenshots": [
+ "01-wevia-master-loaded.png",
+ "99-final.png"
+ ],
+ "end": "2026-04-19T16:04:54",
+ "out_dir": "/var/www/html/api/playwright-results/v76-multi-agent-2026-04-19T16-04-45"
+}
\ No newline at end of file
diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json
index fa3daac01..49a8f555e 100644
--- a/api/v83-business-kpi-latest.json
+++ b/api/v83-business-kpi-latest.json
@@ -1,7 +1,7 @@
{
"ok": true,
"version": "V83-business-kpi",
- "ts": "2026-04-19T14:01:44+00:00",
+ "ts": "2026-04-19T14:04:51+00:00",
"summary": {
"total_categories": 7,
"total_kpis": 56,
diff --git a/api/wevia-pending-loader.php b/api/wevia-pending-loader.php
new file mode 100644
index 000000000..b137cc2e3
--- /dev/null
+++ b/api/wevia-pending-loader.php
@@ -0,0 +1,104 @@
+ /dev', 'systemctl stop',
+ 'systemctl disable', 'shutdown', 'reboot', 'useradd', 'userdel', 'passwd ',
+ '/etc/passwd', '/etc/shadow', 'iptables -F', 'kill -9'];
+ foreach ($BLOCKED as $b) if (stripos($cmd, $b) !== false) return false;
+ foreach ($SAFE as $p) {
+ if (stripos(ltrim($cmd), $p) === 0) return true;
+ if (stripos($cmd, " $p") !== false) return true;
+ }
+ return false;
+}
+
+function wpl_match_intent($message) {
+ $message_lower = strtolower(trim($message));
+ if (strlen($message_lower) < 3) return null;
+ $stubs = glob('/var/www/html/api/wired-pending/intent-opus4-*.php') ?: [];
+ $best = null; $best_score = 0;
+ foreach ($stubs as $s) {
+ $info = @include $s;
+ if (!is_array($info)) continue;
+ if (empty($info['triggers']) || empty($info['cmd'])) continue;
+ if (!empty($info['status']) && $info['status'] === 'PENDING_SECURITY_REVIEW') continue;
+ foreach ($info['triggers'] as $trigger) {
+ $t = strtolower(trim($trigger));
+ if (strlen($t) < 4) continue;
+ // Exact match
+ if ($message_lower === $t) return $info;
+ // Full trigger in message
+ if (strpos($message_lower, $t) !== false) {
+ $score = strlen($t);
+ if ($score > $best_score) { $best = $info; $best_score = $score; }
+ }
+ }
+ }
+ return $best;
+}
+
+function wpl_execute_intent($info) {
+ $name = $info['name'] ?? 'unknown';
+ $cmd = $info['cmd'] ?? '';
+ if (!wpl_is_safe($cmd)) {
+ return [
+ 'ok' => false,
+ 'name' => $name,
+ 'text' => "Intent '$name' detecte mais commande non whitelistee (securite). Review manuel requis.",
+ 'intent' => 'pending_unsafe'
+ ];
+ }
+ $start = microtime(true);
+ $out = @shell_exec("timeout 20 $cmd 2>&1");
+ $ms = round((microtime(true) - $start) * 1000);
+ $text = trim((string)$out);
+ if (strlen($text) > 1500) $text = substr($text, 0, 1500) . "\n... (tronque)";
+ if ($text === '') $text = "Intent '$name' execute (cmd sans output).";
+ wpl_log("MATCH name=$name ms=$ms bytes=" . strlen($text));
+ return [
+ 'ok' => true,
+ 'name' => $name,
+ 'text' => $text,
+ 'intent' => 'pending_' . $name,
+ 'ms' => $ms
+ ];
+}
+
+// Main entry point - supports both standalone API and include
+function wevia_pending_loader($message) {
+ $info = wpl_match_intent($message);
+ if (!$info) return null;
+ return wpl_execute_intent($info);
+}
+
+// If called directly as API
+if (basename($_SERVER['SCRIPT_NAME'] ?? '') === 'wevia-pending-loader.php') {
+ $input = json_decode(file_get_contents("php://input"), true);
+ $message = $input['message'] ?? ($_GET['message'] ?? '');
+ if (!$message) { http_response_code(400); echo json_encode(['error' => 'no message']); exit; }
+ $r = wevia_pending_loader($message);
+ if (!$r) { echo json_encode(['match' => false, 'message' => $message]); exit; }
+ header("Content-Type: text/event-stream");
+ echo "data: " . json_encode([
+ 'type' => 'answer',
+ 'text' => $r['text'],
+ 'engine' => 'PendingLoader/' . $r['name'],
+ 'intent' => $r['intent']
+ ], JSON_UNESCAPED_UNICODE) . "\n\n";
+ echo "data: [DONE]\n\n";
+}