diff --git a/api/ambre-scan-247.php b/api/ambre-scan-247.php new file mode 100644 index 000000000..c10d24660 --- /dev/null +++ b/api/ambre-scan-247.php @@ -0,0 +1,41 @@ +&1 | head -10")))); +$out["recent_commits"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -10")))); + +// Multi-agent infrastructure +$out["multiagent_files"] = []; +foreach (["ambre-master-multiagent.php", "wevia-autonomous.php", "weval-master-api.php", "wevia-multiagent.php", "multiagent-orchestrator.php"] as $f) { + $p = "/var/www/html/api/$f"; + if (file_exists($p)) $out["multiagent_files"][$f] = filesize($p); +} + +// Check wevia.html V9 state +$w = @file_get_contents("/var/www/html/wevia.html"); +$out["wevia"] = [ + "size" => strlen($w), + "v9_wave247_ok_check" => strpos($w, "data.ok || data.success") !== false, + "v9_pattern_widened" => strpos($w, "veux|besoin|demande|fais|cree") !== false, + "v5_memory" => strpos($w, "AMBRE-V5-MEMORY") !== false, + "v10_mermaid" => strpos($w, "AMBRE-V10-MERMAID") !== false, + "mode_select" => strpos($w, "mode.*auto") !== false, +]; + +// Cascade + semaphore +$out["cascade_up"] = @file_get_contents("http://127.0.0.1:4000/health", false, stream_context_create(["http"=>["timeout"=>3]])) ? "UP" : "DOWN"; + +// Recent waves from other Claudes +$out["last_auto_sync"] = trim(@shell_exec("git log --author='autosync\\|weval' --oneline 2>&1 | head -3")); + +// Orchestrator endpoint +$out["orchestrator_api"] = []; +foreach (glob("/var/www/html/api/*orchestr*.php") as $f) { + $out["orchestrator_api"][] = basename($f); +} + +// Current load +$out["load"] = trim(@shell_exec("uptime")); + +echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); diff --git a/api/claude-pattern-sse.php b/api/claude-pattern-sse.php new file mode 100644 index 000000000..54e1b1a63 --- /dev/null +++ b/api/claude-pattern-sse.php @@ -0,0 +1,220 @@ + 0) ob_end_flush(); +ob_implicit_flush(true); + +function emit($event, $data) { + $json = json_encode($data, JSON_UNESCAPED_UNICODE); + echo "event: {$event}\n"; + echo "data: {$json}\n\n"; + @flush(); +} + +$message = trim($_GET['message'] ?? $_POST['message'] ?? ''); +$chatbot = $_GET['chatbot'] ?? $_POST['chatbot'] ?? 'wevia-master'; +$session = $_GET['session'] ?? 'sse-' . bin2hex(random_bytes(3)); + +if (!$message) { + emit('error', ['error' => 'message required']); + exit; +} + +$BACKENDS = [ + 'wevia-master' => '/api/wevia-autonomous.php', + 'wevia' => '/api/ambre-thinking.php', + 'claw' => '/api/wevia-json-api.php', + 'claw-chat' => '/api/wevia-json-api.php', + 'claw-code' => '/api/weval-unified-pipeline.php', + 'director' => '/api/wevia-autonomous.php', + 'director-chat' => '/api/wevia-director.php', + 'ethica' => '/api/ethica-brain.php', + 'ethica-chatbot' => '/api/ethica-brain.php', + 'openclaw' => '/api/openclaw-proxy.php', + 'blade-ai' => '/api/blade-api.php', + 'wevcode' => '/api/wevcode-superclaude.php', + 'wevia-console' => '/api/wevia-json-api.php', + 'wevia-widget' => '/api/wevia-json-api.php', + 'wevia-cortex' => '/api/wevia-stream-api.php', + 'wevia-chat' => '/api/wevia-autonomous.php', + 'sovereign-claude' => '/api/wevia-json-api.php', + 'weval-arena' => '/api/wevia-multi-provider.php', + 'weval-arena-v2' => '/api/wevia-webchat-direct.php', + 'l99-brain' => '/api/wevia-master-api.php', + 'multiagent' => '/api/wevia-v83-multi-agent-orchestrator.php', + 'auto' => '/api/opus5-autonomous-orchestrator-v3.php', +]; + +$backend = $BACKENDS[$chatbot] ?? $BACKENDS['wevia-master']; + +// PHASE 1 · THINKING +$t1 = microtime(true); +emit('thinking', [ + 'status' => 'analyzing', + 'message_length' => strlen($message), + 'chatbot' => $chatbot, + 'backend' => $backend, +]); + +$msg_lower = strtolower($message); +$intent_map = [ + 'status' => ['status', 'état', 'sante', 'health', 'live'], + 'action' => ['rotate', 'restart', 'deploy', 'run', 'exec'], + 'analytics' => ['kpi', 'metric', 'combien', 'total', 'nombre'], +]; +$intent = 'query'; +foreach ($intent_map as $i => $kws) { + foreach ($kws as $kw) { + if (strpos($msg_lower, $kw) !== false) { $intent = $i; break 2; } + } +} + +emit('thinking', [ + 'status' => 'complete', + 'intent' => $intent, + 'duration_ms' => round((microtime(true) - $t1) * 1000, 1), +]); + +// PHASE 2 · PLAN +$t2 = microtime(true); +emit('plan', ['status' => 'building']); + +$steps = match($intent) { + 'status' => ['Query KPI sources', 'Aggregate health data', 'Format response'], + 'action' => ['Validate safety', 'Execute command', 'Verify result'], + 'analytics' => ['Fetch metrics', 'Calculate aggregates', 'Return structured data'], + default => ['Parse query', 'Route to backend', 'Format natural response'], +}; + +emit('plan', [ + 'status' => 'complete', + 'steps' => $steps, + 'duration_ms' => round((microtime(true) - $t2) * 1000, 1), +]); + +// PHASE 3 · RAG (quick ping) +$t3 = microtime(true); +emit('rag', ['status' => 'searching']); + +$rag_ctx = @file_get_contents('http://127.0.0.1:6333/collections', false, stream_context_create([ + 'http' => ['timeout' => 1] +])); +$rag_ok = $rag_ctx !== false; + +emit('rag', [ + 'status' => $rag_ok ? 'qdrant_available' : 'skipped', + 'duration_ms' => round((microtime(true) - $t3) * 1000, 1), +]); + +// PHASE 4 · EXECUTE (REAL backend) +$t4 = microtime(true); +emit('execute', ['status' => 'calling_backend', 'backend' => $backend]); + +$body = json_encode(['message' => $message, 'session' => $session]); +$ctx = stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => "Content-Type: application/json\r\nHost: weval-consulting.com\r\n", + 'content' => $body, + 'timeout' => 25, + 'ignore_errors' => true, + ] +]); + +$backend_resp = @file_get_contents('http://127.0.0.1' . $backend, false, $ctx); +$backend_data = @json_decode($backend_resp, true); + +// Deep-dig text extraction +$text = ''; +if ($backend_data) { + $text = $backend_data['final_response'] + ?? $backend_data['text'] + ?? $backend_data['response'] + ?? $backend_data['answer'] + ?? $backend_data['reply'] + ?? $backend_data['message'] + ?? $backend_data['thinking'] + ?? ''; + if (is_array($text)) $text = json_encode($text, JSON_UNESCAPED_UNICODE); +} + +// Handle SSE chunks if response is SSE format +if (!$text && strpos((string)$backend_resp, 'data:') !== false) { + preg_match_all('/data:\s*(\{[^\n]+\})/', $backend_resp, $m); + $chunks = []; + foreach ($m[1] ?? [] as $chunk) { + $cd = @json_decode($chunk, true); + if (!empty($cd['text'])) $chunks[] = $cd['text']; + } + $text = implode("\n", $chunks); +} + +$backend_ok = !empty($text) && strlen($text) > 10; + +emit('execute', [ + 'status' => 'complete', + 'backend_ok' => $backend_ok, + 'response_length' => strlen($text), + 'duration_ms' => round((microtime(true) - $t4) * 1000, 1), +]); + +// PHASE 5 · TESTS +$t5 = microtime(true); +$tests = [ + 'has_response' => $backend_ok, + 'no_error' => !preg_match('/\berror\b|\bfailed\b|\bexception\b/i', substr($text, 0, 200)), + 'not_simulated' => !preg_match('/simulat(ed|ion)|mock|fake|placeholder/i', substr($text, 0, 300)), + 'not_hallucinating' => !preg_match('/\b(je ne sais pas|imagine|hypothetical|suppose que|probablement|might be)\b/i', substr($text, 0, 300)), + 'has_natural_lang' => preg_match('/\b(le|la|les|un|je|vous|nous|est|sont|the|is|are)\b/i', substr($text, 0, 200)) > 0, +]; +$passed = array_sum(array_map('intval', $tests)); + +emit('tests', [ + 'passed' => $passed, + 'total' => count($tests), + 'details' => $tests, + 'duration_ms' => round((microtime(true) - $t5) * 1000, 1), +]); + +// PHASE 6 · RESPONSE +emit('response', [ + 'text' => $text, + 'length' => strlen($text), +]); + +// PHASE 7 · CRITIQUE +$notes = []; +if ($passed < 5) $notes[] = "Some tests failed ({$passed}/5)"; +if (strlen($text) < 30) $notes[] = "Short response"; +if ((microtime(true) - $t4) > 10) $notes[] = "Slow response"; +if (!$notes) $notes[] = "Quality OK"; + +emit('critique', [ + 'quality_score' => $passed / 5, + 'quality' => $passed === 5 ? 'EXCELLENT' : ($passed >= 4 ? 'GOOD' : ($passed >= 3 ? 'OK' : 'LOW')), + 'notes' => $notes, +]); + +// DONE +emit('done', [ + 'total_duration_ms' => round((microtime(true) - $t1) * 1000, 1), + 'chatbot' => $chatbot, + 'session' => $session, +]); diff --git a/api/em-kpi-cache.json b/api/em-kpi-cache.json index e69de29bb..2131a98e6 100644 --- a/api/em-kpi-cache.json +++ b/api/em-kpi-cache.json @@ -0,0 +1,286 @@ +{ + "ts": "2026-04-22T02:35:01+00:00", + "server": "s204", + "s204": { + "load": 4.35, + "uptime": "2026-04-14 11:51:24", + "ram_total_mb": 31335, + "ram_used_mb": 13486, + "ram_free_mb": 17848, + "disk_total": "150G", + "disk_used": "122G", + "disk_free": "22G", + "disk_pct": "85%", + "fpm_workers": 141, + "docker_containers": 19, + "cpu_cores": 8 + }, + "s95": { + "load": 1.96, + "disk_pct": "82%", + "status": "UP", + "ram_total_mb": 15610, + "ram_free_mb": 12010 + }, + "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": 324, + "php_apis": 1013, + "wiki_entries": 2252, + "vault_doctrines": 109, + "vault_sessions": 104, + "vault_decisions": 12 + }, + "tools": { + "total": 645, + "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": 165260, + "with_email": 110678, + "with_phone": 158152, + "gap_email": 54582, + "pct_email": 67, + "pct_phone": 95.7, + "by_country": [ + { + "country": "DZ", + "hcps": 125863, + "with_email": 78567, + "with_tel": 122397, + "pct_email": 62.4, + "pct_tel": 97.2 + }, + { + "country": "MA", + "hcps": 19724, + "with_email": 15081, + "with_tel": 18737, + "pct_email": 76.5, + "pct_tel": 95 + }, + { + "country": "TN", + "hcps": 17794, + "with_email": 15151, + "with_tel": 17018, + "pct_email": 85.1, + "pct_tel": 95.6 + }, + { + "country": "INTL", + "hcps": 1879, + "with_email": 1879, + "with_tel": 0, + "pct_email": 100, + "pct_tel": 0 + } + ] + }, + "docker": [ + { + "name": "weval-docuseal", + "status": "Up 9 seconds", + "ports": "" + }, + { + "name": "loki", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "listmonk", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "plausible-plausible-1", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "plausible-plausible-db-1", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "plausible-plausible-events-db-1", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "n8n-docker-n8n-1", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "mattermost-docker-mm-db-1", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "mattermost-docker-mattermost-1", + "status": "Up 5 days (healthy)", + "ports": "" + }, + { + "name": "twenty", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "twenty-redis", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "langfuse", + "status": "Up 6 days", + "ports": "" + }, + { + "name": "redis-weval", + "status": "Up 7 days", + "ports": "" + }, + { + "name": "gitea", + "status": "Up 7 days", + "ports": "" + }, + { + "name": "node-exporter", + "status": "Up 7 days", + "ports": "" + }, + { + "name": "prometheus", + "status": "Up 7 days", + "ports": "" + }, + { + "name": "searxng", + "status": "Up 7 days", + "ports": "" + }, + { + "name": "uptime-kuma", + "status": "Up 2 days (healthy)", + "ports": "" + }, + { + "name": "vaultwarden", + "status": "Up 7 days (healthy)", + "ports": "" + }, + { + "name": "qdrant", + "status": "Up 7 days", + "ports": "" + } + ], + "crons": { + "active": 35 + }, + "git": { + "head": "6a1f27480 auto-sync-0435", + "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": 4363, + "health": { + "score": 6, + "max": 6, + "pct": 100 + }, + "elapsed_ms": 11068 +} \ No newline at end of file diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/01-01-master-loaded.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/01-01-master-loaded.png new file mode 100644 index 000000000..7ed134895 Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/01-01-master-loaded.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/02-02-question-set.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/02-02-question-set.png new file mode 100644 index 000000000..0cc0684ed Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/02-02-question-set.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/03-03-just-after-send.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/03-03-just-after-send.png new file mode 100644 index 000000000..ea94b6a76 Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/03-03-just-after-send.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/04-04-phases-streaming-1.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/04-04-phases-streaming-1.png new file mode 100644 index 000000000..8c08bfb96 Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/04-04-phases-streaming-1.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/05-05-phases-streaming-2.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/05-05-phases-streaming-2.png new file mode 100644 index 000000000..bbc61ce5e Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/05-05-phases-streaming-2.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/06-06-phases-streaming-3.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/06-06-phases-streaming-3.png new file mode 100644 index 000000000..3f6b377cf Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/06-06-phases-streaming-3.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/07-07-phases-streaming-4.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/07-07-phases-streaming-4.png new file mode 100644 index 000000000..86495a5dd Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/07-07-phases-streaming-4.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/08-08-phases-streaming-5.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/08-08-phases-streaming-5.png new file mode 100644 index 000000000..950b7332c Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/08-08-phases-streaming-5.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/09-09-phases-streaming-6.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/09-09-phases-streaming-6.png new file mode 100644 index 000000000..2a836f171 Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/09-09-phases-streaming-6.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/10-010-phases-streaming-7.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/10-010-phases-streaming-7.png new file mode 100644 index 000000000..0a2d6cdd2 Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/10-010-phases-streaming-7.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/11-11-final-state.png b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/11-11-final-state.png new file mode 100644 index 000000000..35be3df5f Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/11-11-final-state.png differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/page@6f04b35ebba9b468a731711c5228cbb1.webm b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/page@6f04b35ebba9b468a731711c5228cbb1.webm new file mode 100644 index 000000000..7178a88ef Binary files /dev/null and b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/page@6f04b35ebba9b468a731711c5228cbb1.webm differ diff --git a/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/results.json b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/results.json new file mode 100644 index 000000000..110a31c36 --- /dev/null +++ b/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/results.json @@ -0,0 +1,46 @@ +{ + "ts": "2026-04-22T02-35-23-094Z", + "version": "V170", + "tests": [ + { + "name": "login", + "pass": true + }, + { + "name": "v166_wired", + "pass": true + }, + { + "name": "question_sent", + "pass": true, + "inputCleared": true, + "msgCount": 2 + }, + { + "name": "thinking_panel_shown", + "pass": false, + "visible": false + }, + { + "name": "phases_streamed", + "pass": false, + "lines_count": 0, + "lines_sample": [] + }, + { + "name": "stages_progressed", + "pass": false, + "stages_done": 0 + }, + { + "name": "got_response", + "pass": true, + "latest": "PROVIDERS IA: 17 cles API + 1 modeles WEVIA Engine localCascade: WEVIA Engine > HF > NVIDIA > WEVIA Engine > WEVIA Engine > WEVIA Engine > WEVIA EngineCout: 0 eurosCopierSupprimerExec0.1s" + } + ], + "video": "/var/www/html/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/page@6f04b35ebba9b468a731711c5228cbb1.webm", + "screenshots_dir": "/var/www/html/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z", + "pass_total": 4, + "fail_total": 3, + "all_pass": false +} \ No newline at end of file diff --git a/api/playwright-v170-latest.json b/api/playwright-v170-latest.json new file mode 100644 index 000000000..110a31c36 --- /dev/null +++ b/api/playwright-v170-latest.json @@ -0,0 +1,46 @@ +{ + "ts": "2026-04-22T02-35-23-094Z", + "version": "V170", + "tests": [ + { + "name": "login", + "pass": true + }, + { + "name": "v166_wired", + "pass": true + }, + { + "name": "question_sent", + "pass": true, + "inputCleared": true, + "msgCount": 2 + }, + { + "name": "thinking_panel_shown", + "pass": false, + "visible": false + }, + { + "name": "phases_streamed", + "pass": false, + "lines_count": 0, + "lines_sample": [] + }, + { + "name": "stages_progressed", + "pass": false, + "stages_done": 0 + }, + { + "name": "got_response", + "pass": true, + "latest": "PROVIDERS IA: 17 cles API + 1 modeles WEVIA Engine localCascade: WEVIA Engine > HF > NVIDIA > WEVIA Engine > WEVIA Engine > WEVIA Engine > WEVIA EngineCout: 0 eurosCopierSupprimerExec0.1s" + } + ], + "video": "/var/www/html/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z/page@6f04b35ebba9b468a731711c5228cbb1.webm", + "screenshots_dir": "/var/www/html/api/playwright-results/v170-wevia-master-real-chat-2026-04-22T02-35-23-094Z", + "pass_total": 4, + "fail_total": 3, + "all_pass": false +} \ No newline at end of file diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json index c5df01a00..3f9c18a99 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-22T02:34:42+00:00", + "ts": "2026-04-22T02:35:21+00:00", "summary": { "total_categories": 8, "total_kpis": 64,