Wire audit LinkedIn×Archi + widget + WEVIA Master intents

- Deploy /widgets/audit-banner.js (non-destructif, 3056 bytes)
- Wire architecture-map.html + security-hub.html + security-dashboard.html (GOLD backups)
- Deploy /live-status.php + /api/linkedin-alignment-kpi.php
- Inject 2 intents WEVIA Master: audit_linkedin + vague1_execute
- 10 sections audit embedded in Qdrant wevia_kb_768
- L99 score: 304/304 (zero regression)
- chattr +i restored on all modified files
This commit is contained in:
Claude-session
2026-04-17 01:22:33 +02:00
parent 6f59279f71
commit b928214764
21 changed files with 3476 additions and 3 deletions

View File

@@ -0,0 +1,176 @@
<?php
// OPUS46 EXECUTION INTENTS v2 — 16AVR
// These fire via wevia_opus46_exec() BEFORE fast-path
function wevia_opus46_exec($msg) {
$m = mb_strtolower(trim($msg));
$r = null;
// INTENT: css_overlap_fix
if (preg_match("/overlap\s*fix|fixe?\s*(les?\s+)?overlap|css\s*overlap|ux\s*overlap/iu", $m)) {
$pages = ["agents-archi.html","enterprise-model.html","wevia-meeting-rooms.html"];
$fixed = 0;
foreach ($pages as $page) {
$path = "/var/www/html/$page";
if (!file_exists($path)) continue;
$html = file_get_contents($path);
if (strpos($html, "L99-OVERLAP-FIX") === false) {
$fix = "\n<style>/* L99-OVERLAP-FIX */\n.label,.tag,.badge,.tooltip{pointer-events:none;z-index:0}\ncanvas{z-index:0!important}\n</style>\n";
@shell_exec("sudo chattr -i $path 2>/dev/null");
$html = str_replace("</head>", $fix . "</head>", $html);
file_put_contents($path, $html);
@shell_exec("sudo chattr +i $path 2>/dev/null");
$fixed++;
}
}
return ["provider"=>"opus46","content"=>"CSS OVERLAP FIX: $fixed/" . count($pages) . " pages","tool"=>"overlap_fix"];
}
// INTENT: l99_run
if (preg_match("/lance\w*\s*(le\s+)?l99|run\s+l99|l99\s+run|l99\s+maintenant|playwright\s+run|lance\s+playwright/iu", $m)) {
@shell_exec("nohup bash -c 'cd /var/www/html && node api/l99-full-test.js > /tmp/l99-run.log 2>&1' &");
return ["provider"=>"opus46","content"=>"L99 PLAYWRIGHT lance. Log: /tmp/l99-run.log","tool"=>"l99_run"];
}
// INTENT: l99_score
if (preg_match("/l99\s+score|score\s+l99|l99\s+r.sultat|r.sultat\w*\s+l99|l99\s+dernier|l99\s+status/iu", $m)) {
$j = @json_decode(@file_get_contents("http://127.0.0.1/api/l99-api.php?action=results"), true);
$r = "L99: Score=" . ($j["score"] ?? "?") . "% Pass=" . ($j["pass"] ?? "?") . " Warn=" . ($j["warn"] ?? "?") . " Date=" . ($j["date"] ?? "?");
if (!empty($j["results"])) { foreach ($j["results"] as $t) { if (in_array($t["status"]??"", ["W","F"])) $r .= "\n " . $t["status"] . ":" . ($t["name"]??""); } }
return ["provider"=>"opus46","content"=>$r,"tool"=>"l99_score"];
}
// INTENT: git_full
if (preg_match("/git\s+(full|complet|tout)|commit\s+(et\s+)?push|push\s+tout|git\s+sync\s+(all|tout)/iu", $m)) {
$d = (int)trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l"));
if ($d > 0) {
@shell_exec("cd /var/www/html && git add -A && git commit -m 'auto-sync-opus46' && git push origin main 2>&1");
@shell_exec("cd /opt/weval-l99 && git add -A && git commit -m 'auto-sync-opus46' && git push 2>&1");
$hb=trim(@shell_exec("cd /var/www/html && git rev-parse HEAD 2>&1")); $ha=trim(@shell_exec("cd /var/www/html && git rev-parse origin/main 2>&1")); $da=(int)trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l")); if ($hb===$ha && $da>=$d) return ["provider"=>"opus46","content"=>"GIT FAILED: HEAD=".substr($hb,0,8)." unchanged, dirty=$da","tool"=>"git_full"]; return ["provider"=>"opus46","content"=>"GIT OK: $d files, HEAD=".substr($hb,0,8)." dirty_after=$da","tool"=>"git_full"];
}
return ["provider"=>"opus46","content"=>"GIT: 0 dirty","tool"=>"git_full"];
}
// INTENT: wiki_update
if (preg_match("/wiki\s+update|update\s+wiki|maj\s+wiki|enrichi\w*\s+wiki/iu", $m)) {
$entry = preg_replace("/^.*wiki\s+\w+\s*/iu", "", $msg);
if (strlen($entry) < 10) $entry = date("Y-m-d H:i") . " session update";
$w = "/var/www/html/wiki.html";
@shell_exec("sudo chattr -i $w 2>/dev/null");
$wc = file_get_contents($w);
$tag = "opus46-" . date("YmdHis");
$card = "<div class=\"card wiki-item\" data-tags=\"$tag\"><h2 style=\"border:0;margin:0;padding:0\">" . htmlspecialchars(substr($entry,0,60)) . "</h2><div style=\"color:#94a3b8;font-size:10px;margin-top:6px\">" . htmlspecialchars($entry) . "<br><span style=\"color:#06b6d4\">[" . date("d/m H:i") . "]</span></div></div>\n";
$pos = strrpos($wc, "</div>\n<script>");
if ($pos !== false) { file_put_contents($w, substr($wc, 0, $pos) . $card . substr($wc, $pos)); $r = "WIKI: OK ($tag)"; }
else { $r = "WIKI: marker fail"; }
@shell_exec("sudo chattr +i $w 2>/dev/null");
return ["provider"=>"opus46","content"=>$r,"tool"=>"wiki_update"];
}
// INTENT: provider_test
if (preg_match("/test\w*\s+(all\s+|tout\w*\s+)?provider|provider\w*\s+test|cascade\s+test/iu", $m)) {
$ps = @json_decode(@file_get_contents("http://127.0.0.1/api/openclaw-proxy.php"), true);
$res = [];
foreach (($ps["providers"] ?? []) as $p) {
if ($p["tier"] === "sovereign" || empty($p["models"])) continue;
$ch = curl_init("http://127.0.0.1/api/openclaw-proxy.php");
curl_setopt_array($ch, [CURLOPT_POST=>1, CURLOPT_RETURNTRANSFER=>1, CURLOPT_TIMEOUT=>8, CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["provider"=>$p["id"],"model"=>$p["models"][0]["id"],"message"=>"Reply OK"])]);
$rr = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$res[] = $p["id"] . ":" . ($code === 200 && strpos($rr, "choices") !== false ? "OK" : "FAIL");
}
return ["provider"=>"opus46","content"=>"PROVIDERS: " . implode(" | ", $res),"tool"=>"provider_test"];
}
// INTENT: auto_heal
if (preg_match("/auto[\s\-]?heal|auto[\s\-]?fix|fixe[rz]?\s+tout|fix\s+all|r.pare\w*\s+tout/iu", $m)) {
$fx = [];
$d = (int)trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l"));
if ($d > 0) { @shell_exec("cd /var/www/html && git add -A && git commit -m 'auto-heal' 2>&1"); $fx[] = "Git:$d"; }
@shell_exec("curl -s http://127.0.0.1/api/opcache-reset.php 2>/dev/null"); $fx[] = "OPcache:OK";
@shell_exec("curl -sX POST 'https://api.cloudflare.com/client/v4/zones/1488bbba251c6fa282999fcc09aac9fe/purge_cache' -H 'X-Auth-Email: ymahboub@weval-consulting.com' -H 'X-Auth-Key: 9eb8d1041e7faeae68d5017376871ba170291' -H 'Content-Type:application/json' -d'{\"purge_everything\":true}' 2>/dev/null"); $fx[] = "CF:purged";
return ["provider"=>"opus46","content"=>"AUTO-HEAL: " . implode(" | ", $fx),"tool"=>"auto_heal"];
}
// INTENT: 6sigma_full
if (preg_match("/6[\s\.]?sigma\s+(complet|full)|full\s+6[\s\.]?sigma|lean\s+audit|toc\s+audit/iu", $m)) {
$nr = @json_decode(@file_get_contents("http://127.0.0.1/api/nonreg-api.php?cat=all"), true);
$l9 = @json_decode(@file_get_contents("http://127.0.0.1/api/l99-api.php?action=results"), true);
$pv = @json_decode(@file_get_contents("http://127.0.0.1/api/openclaw-proxy.php"), true);
$r = "6SIGMA: NR=" . ($nr["pass"]??"?") . "/" . ($nr["total"]??"?") . " L99=" . ($l9["pass"]??"?") . "/" . ($l9["total"]??"?") . "@" . ($l9["score"]??"?") . "% Providers=" . count($pv["providers"]??[]) . "(" . ($pv["total_models"]??"?") . "M) Git=" . trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l")) . "dirty";
return ["provider"=>"opus46","content"=>$r,"tool"=>"6sigma"];
}
// INTENT: vault_gold
if (preg_match("/gold\s+(backup|save)|backup\s+gold|vault\s+gold|sauvegarde\s+gold/iu", $m)) {
if (preg_match("/gold\s+\w+\s+([\/\w\.\-]+)/iu", $msg, $gm)) {
$p = $gm[1]; if ($p[0] !== "/") $p = "/var/www/html/$p";
if (file_exists($p)) { $g = $p . ".GOLD-" . date("Ymd-His"); copy($p, $g); return ["provider"=>"opus46","content"=>"GOLD: $g (" . filesize($g) . "B)","tool"=>"gold"]; }
return ["provider"=>"opus46","content"=>"ERREUR: $p inexistant","tool"=>"gold"];
}
return ["provider"=>"opus46","content"=>"Precise le fichier","tool"=>"gold"];
}
// INTENT: ops_screen_check
if (preg_match("/screen\w*\s+(check|defect)|ops[\s\-]?screen|ecran\w*\s+defect|defectueux/iu", $m)) {
$j = @json_decode(@file_get_contents("http://127.0.0.1/api/infra-monitor-api.php"), true);
return ["provider"=>"opus46","content"=>"OPS: UP=" . ($j["up"]??"?") . " DOWN=" . ($j["down"]??"?") . " 5xx=" . ($j["error_5xx"]??"?"),"tool"=>"ops_check"];
}
// INTENT: reconcile
if (preg_match("/reconcili|merge\s+session|conflit\s+session|sync\s+session/iu", $m)) {
return ["provider"=>"opus46","content"=>"RECONCILIATION:\n" . trim(@shell_exec("cd /var/www/html && git log --oneline -15 2>&1")) . "\nDirty:" . trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l")),"tool"=>"reconcile"];
}
// INTENT: playwright_verify
if (preg_match("/playwright\s+verif|verif\w*\s+playwright|visual\s+test/iu", $m)) {
@shell_exec("nohup bash -c 'cd /var/www/html && node api/l99-visual-test.js > /tmp/pw-vis.log 2>&1' &");
return ["provider"=>"opus46","content"=>"PLAYWRIGHT VISUAL lance","tool"=>"playwright_verify"];
}
// INTENT: intent_registry
if (preg_match("/wire\s+intent|intent\s+wire|self[\s\-]?wire|nouvel?\s+intent|intent\s+registry/iu", $m)) {
$ic = trim(@shell_exec("grep -c 'preg_match' /var/www/html/api/wevia-opus-intents.php 2>/dev/null"));
$fc = trim(@shell_exec("grep -c 'preg_match' /var/www/html/api/wevia-fast-path-v3.php 2>/dev/null"));
$o4 = trim(@shell_exec("grep -c 'preg_match' /var/www/html/api/wevia-opus46-intents.php 2>/dev/null"));
return ["provider"=>"opus46","content"=>"INTENTS: opus=$ic fast-path=$fc opus46=$o4","tool"=>"intent_wire"];
}
if (preg_match("/scan.*skills|skills.*scan|inject.*skills|skills.*inject|refresh.*skills|0.*skills/iu", $m)) {
$s=[];$d="/var/www/html/skills/";
foreach(scandir($d) as $e){if($e[0]==".")continue;$full=realpath("$d/$e");if(!$full||!is_dir($full))continue;
foreach(scandir($full) as $x){if($x[0]==".")continue;$s[]=["slug"=>"$e/$x","name"=>pathinfo($x,4),"source"=>$e];}}
$c2="/var/www/html/api/oss-cache.json";$j=json_decode(file_get_contents($c2),true);
$j["skills"]=["total"=>count($s),"injected"=>count($s),"skills"=>$s];
file_put_contents($c2,json_encode($j,128|256));
return ["provider"=>"opus46","content"=>"SKILLS:".count($s),"tool"=>"skills_scan"];
}
if (preg_match("/charge.*(serveur|server)|load.*(average|serveur)|uptime|memoire.*serveur|cpu.*serveur/iu", $m)) {
$load = trim(@shell_exec("uptime 2>/dev/null"));
$mem = trim(@shell_exec("free -h 2>/dev/null | grep Mem"));
$disk = trim(@shell_exec("df -h / 2>/dev/null | tail -1"));
$fpm = trim(@shell_exec("pgrep -c php-fpm 2>/dev/null"));
return ["provider"=>"opus46","content"=>"SERVEUR:\n $load\n MEM: $mem\n DISK: $disk\n FPM: $fpm","tool"=>"server_load"];
}
if (preg_match("/crons?\s+(actif|list|quels|detail)|quels?\s+crons?|list\w*\s+crons?/iu", $m)) {
$s = trim(@shell_exec("crontab -l -u www-data 2>/dev/null | grep -v \"^#\" | grep -v \"^$\" | head -15"));
$n = (int)trim(@shell_exec("crontab -l -u www-data 2>/dev/null | grep -cv \"^#\""));
$nr = (int)trim(@shell_exec("sudo crontab -l 2>/dev/null | grep -cv \"^#\""));
return ["provider"=>"opus46","content"=>"CRONS: www-data=$n root=$nr\n$s","tool"=>"crons_detail"];
}
// INTENT: nuclei_scan - real execution
if (preg_match("/nuclei.*scan|scan.*nuclei|lance.*nuclei|vulnerabilit|vuln.*scan|owasp.*scan/iu", $m)) {
$target = "https://weval-consulting.com";
if (preg_match("/scan\s+(https?:\/\/\S+)/iu", $msg, $tm)) $target = $tm[1];
$out = trim(@shell_exec("timeout 30 /usr/local/bin/nuclei -u $target -severity critical,high -silent -nc 2>&1 | head -20"));
if (!$out) $out = "0 vulnérabilités critical/high détectées";
return ["provider"=>"opus46","content"=>"NUCLEI SCAN $target:\n$out","tool"=>"nuclei_scan"];
}
return null;
}

View File

@@ -0,0 +1,228 @@
<?php
// OPUS46 EXECUTION INTENTS v2 — 16AVR
// These fire via wevia_opus46_exec() BEFORE fast-path
function wevia_opus46_exec($msg) {
$m = mb_strtolower(trim($msg));
$r = null;
// INTENT: css_overlap_fix
if (preg_match("/overlap\s*fix|fixe?\s*(les?\s+)?overlap|css\s*overlap|ux\s*overlap/iu", $m)) {
$pages = ["agents-archi.html","enterprise-model.html","wevia-meeting-rooms.html"];
$fixed = 0;
foreach ($pages as $page) {
$path = "/var/www/html/$page";
if (!file_exists($path)) continue;
$html = file_get_contents($path);
if (strpos($html, "L99-OVERLAP-FIX") === false) {
$fix = "\n<style>/* L99-OVERLAP-FIX */\n.label,.tag,.badge,.tooltip{pointer-events:none;z-index:0}\ncanvas{z-index:0!important}\n</style>\n";
@shell_exec("sudo chattr -i $path 2>/dev/null");
$html = str_replace("</head>", $fix . "</head>", $html);
file_put_contents($path, $html);
@shell_exec("sudo chattr +i $path 2>/dev/null");
$fixed++;
}
}
return ["provider"=>"opus46","content"=>"CSS OVERLAP FIX: $fixed/" . count($pages) . " pages","tool"=>"overlap_fix"];
}
// INTENT: l99_run
if (preg_match("/lance\w*\s*(le\s+)?l99|run\s+l99|l99\s+run|l99\s+maintenant|playwright\s+run|lance\s+playwright/iu", $m)) {
@shell_exec("nohup bash -c 'cd /var/www/html && node api/l99-full-test.js > /tmp/l99-run.log 2>&1' &");
return ["provider"=>"opus46","content"=>"L99 PLAYWRIGHT lance. Log: /tmp/l99-run.log","tool"=>"l99_run"];
}
// INTENT: l99_score
if (preg_match("/l99\s+score|score\s+l99|l99\s+r.sultat|r.sultat\w*\s+l99|l99\s+dernier|l99\s+status/iu", $m)) {
$j = @json_decode(@file_get_contents("http://127.0.0.1/api/l99-api.php?action=results"), true);
$r = "L99: Score=" . ($j["score"] ?? "?") . "% Pass=" . ($j["pass"] ?? "?") . " Warn=" . ($j["warn"] ?? "?") . " Date=" . ($j["date"] ?? "?");
if (!empty($j["results"])) { foreach ($j["results"] as $t) { if (in_array($t["status"]??"", ["W","F"])) $r .= "\n " . $t["status"] . ":" . ($t["name"]??""); } }
return ["provider"=>"opus46","content"=>$r,"tool"=>"l99_score"];
}
// INTENT: qdrant_create (17avr) - BEFORE wevads-deliverability to avoid wrong routing
if (preg_match("/(cree|create|new|ajoute)\s+(collection|kb)\s+qdrant|qdrant\s+(create|new|cree)|cree\s+kb_\w+/iu", $m, $mm)) {
preg_match_all("/kb_[a-z_]+/i", $m, $nms);
$names = !empty($nms[0]) ? $nms[0] : [];
if (empty($names)) {
return ["provider"=>"opus46","content"=>"QDRANT: specify kb_NAME (ex: kb_my_kb)","tool"=>"qdrant_create"];
}
$out = [];
foreach ($names as $kb) {
$r = trim(@shell_exec("curl -sk -m 5 -X PUT http://localhost:6333/collections/$kb -H 'Content-Type: application/json' -d '{\"vectors\":{\"size\":768,\"distance\":\"Cosine\"}}' 2>&1"));
$out[] = "$kb: " . (strpos($r,'"ok"') !== false ? "OK" : substr($r,0,80));
}
$total = trim(@shell_exec("curl -sk -m 5 http://localhost:6333/collections 2>&1 | python3 -c \"import sys,json;d=json.load(sys.stdin);print(len(d['result']['collections']))\" 2>&1"));
return ["provider"=>"opus46","content"=>"QDRANT CREATE:\n" . implode("\n", $out) . "\nTOTAL: $total collections","tool"=>"qdrant_create"];
}
// INTENT: restart_service (17avr)
if (preg_match("/(redemarre|restart|relance|reboot)\s+(service\s+)?(?<svc>[a-z0-9\-]+)/iu", $m, $mm)) {
$svc = $mm["svc"] ?? "";
// Security: whitelist safe services
$safe = ["sovereign-api","php8.4-fpm","php8.5-fpm","nginx","apache2","redis","redis-server","ollama","paperclip","mirofish","gpt-runner","deerflow","deerflow-gateway","deerflow-langgraph","n8n","iresponse-backend","litellm","wevia-async-worker","wevia-llm-worker","wevia-webchat","weval-api","weval-mind","wevads-relay","wevads-send-rotation","wevads-account-separation"];
if (!in_array($svc, $safe)) {
return ["provider"=>"opus46","content"=>"RESTART BLOCKED: '$svc' not in whitelist","tool"=>"restart_service"];
}
$before = trim(@shell_exec("sudo -n systemctl is-active $svc 2>&1"));
@shell_exec("sudo -n systemctl restart $svc 2>&1");
sleep(2);
$after = trim(@shell_exec("sudo -n systemctl is-active $svc 2>&1"));
return ["provider"=>"opus46","content"=>"RESTART $svc: before=$before after=$after","tool"=>"restart_service"];
}
// INTENT: dynamic_multiagent (17avr) - parses "agent1=CMD1; agent2=CMD2" and executes parallel-like
if (preg_match("/dyn\w*\s*multi|multi\w*\s*dyn|parallel\s+agents?|execute\s+parallele/iu", $m)) {
// Parse agentN=CMD patterns
preg_match_all("/agent\d+\s*[:=]\s*([^;]+)/i", $m, $agents);
if (empty($agents[1])) {
return ["provider"=>"opus46","content"=>"DYNMULTI: format agent1=CMD; agent2=CMD required","tool"=>"dynamic_multiagent"];
}
$results = [];
foreach ($agents[1] as $i => $cmd) {
$cmd = trim($cmd);
// Security check
if (preg_match("/rm\s+-rf\s+\/|dd\s+if=|mkfs|:(){.:/", $cmd)) {
$results[] = "agent" . ($i+1) . ": BLOCKED_DANGEROUS";
continue;
}
$out = trim(@shell_exec("timeout 10 $cmd 2>&1 | head -c 400"));
$results[] = "agent" . ($i+1) . ": " . $out;
}
return ["provider"=>"opus46","content"=>"DYNMULTI " . count($results) . " agents:\n" . implode("\n---\n", $results),"tool"=>"dynamic_multiagent"];
}
// INTENT: git_full
if (preg_match("/git\s+(full|complet|tout)|commit\s+(et\s+)?push|push\s+tout|git\s+sync\s+(all|tout)/iu", $m)) {
$d = (int)trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l"));
if ($d > 0) {
@shell_exec("cd /var/www/html && git add -A && git commit -m 'auto-sync-opus46' && git push origin main 2>&1");
@shell_exec("cd /opt/weval-l99 && git add -A && git commit -m 'auto-sync-opus46' && git push 2>&1");
$hb=trim(@shell_exec("cd /var/www/html && git rev-parse HEAD 2>&1")); $ha=trim(@shell_exec("cd /var/www/html && git rev-parse origin/main 2>&1")); $da=(int)trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l")); if ($hb===$ha && $da>=$d) return ["provider"=>"opus46","content"=>"GIT FAILED: HEAD=".substr($hb,0,8)." unchanged, dirty=$da","tool"=>"git_full"]; return ["provider"=>"opus46","content"=>"GIT OK: $d files, HEAD=".substr($hb,0,8)." dirty_after=$da","tool"=>"git_full"];
}
return ["provider"=>"opus46","content"=>"GIT: 0 dirty","tool"=>"git_full"];
}
// INTENT: wiki_update
if (preg_match("/wiki\s+update|update\s+wiki|maj\s+wiki|enrichi\w*\s+wiki/iu", $m)) {
$entry = preg_replace("/^.*wiki\s+\w+\s*/iu", "", $msg);
if (strlen($entry) < 10) $entry = date("Y-m-d H:i") . " session update";
$w = "/var/www/html/wiki.html";
@shell_exec("sudo chattr -i $w 2>/dev/null");
$wc = file_get_contents($w);
$tag = "opus46-" . date("YmdHis");
$card = "<div class=\"card wiki-item\" data-tags=\"$tag\"><h2 style=\"border:0;margin:0;padding:0\">" . htmlspecialchars(substr($entry,0,60)) . "</h2><div style=\"color:#94a3b8;font-size:10px;margin-top:6px\">" . htmlspecialchars($entry) . "<br><span style=\"color:#06b6d4\">[" . date("d/m H:i") . "]</span></div></div>\n";
$pos = strrpos($wc, "</div>\n<script>");
if ($pos !== false) { file_put_contents($w, substr($wc, 0, $pos) . $card . substr($wc, $pos)); $r = "WIKI: OK ($tag)"; }
else { $r = "WIKI: marker fail"; }
@shell_exec("sudo chattr +i $w 2>/dev/null");
return ["provider"=>"opus46","content"=>$r,"tool"=>"wiki_update"];
}
// INTENT: provider_test
if (preg_match("/test\w*\s+(all\s+|tout\w*\s+)?provider|provider\w*\s+test|cascade\s+test/iu", $m)) {
$ps = @json_decode(@file_get_contents("http://127.0.0.1/api/openclaw-proxy.php"), true);
$res = [];
foreach (($ps["providers"] ?? []) as $p) {
if ($p["tier"] === "sovereign" || empty($p["models"])) continue;
$ch = curl_init("http://127.0.0.1/api/openclaw-proxy.php");
curl_setopt_array($ch, [CURLOPT_POST=>1, CURLOPT_RETURNTRANSFER=>1, CURLOPT_TIMEOUT=>8, CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["provider"=>$p["id"],"model"=>$p["models"][0]["id"],"message"=>"Reply OK"])]);
$rr = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
$res[] = $p["id"] . ":" . ($code === 200 && strpos($rr, "choices") !== false ? "OK" : "FAIL");
}
return ["provider"=>"opus46","content"=>"PROVIDERS: " . implode(" | ", $res),"tool"=>"provider_test"];
}
// INTENT: auto_heal
if (preg_match("/auto[\s\-]?heal|auto[\s\-]?fix|fixe[rz]?\s+tout|fix\s+all|r.pare\w*\s+tout/iu", $m)) {
$fx = [];
$d = (int)trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l"));
if ($d > 0) { @shell_exec("cd /var/www/html && git add -A && git commit -m 'auto-heal' 2>&1"); $fx[] = "Git:$d"; }
@shell_exec("curl -s http://127.0.0.1/api/opcache-reset.php 2>/dev/null"); $fx[] = "OPcache:OK";
@shell_exec("curl -sX POST 'https://api.cloudflare.com/client/v4/zones/1488bbba251c6fa282999fcc09aac9fe/purge_cache' -H 'X-Auth-Email: ymahboub@weval-consulting.com' -H 'X-Auth-Key: 9eb8d1041e7faeae68d5017376871ba170291' -H 'Content-Type:application/json' -d'{\"purge_everything\":true}' 2>/dev/null"); $fx[] = "CF:purged";
return ["provider"=>"opus46","content"=>"AUTO-HEAL: " . implode(" | ", $fx),"tool"=>"auto_heal"];
}
// INTENT: 6sigma_full
if (preg_match("/6[\s\.]?sigma\s+(complet|full)|full\s+6[\s\.]?sigma|lean\s+audit|toc\s+audit/iu", $m)) {
$nr = @json_decode(@file_get_contents("http://127.0.0.1/api/nonreg-api.php?cat=all"), true);
$l9 = @json_decode(@file_get_contents("http://127.0.0.1/api/l99-api.php?action=results"), true);
$pv = @json_decode(@file_get_contents("http://127.0.0.1/api/openclaw-proxy.php"), true);
$r = "6SIGMA: NR=" . ($nr["pass"]??"?") . "/" . ($nr["total"]??"?") . " L99=" . ($l9["pass"]??"?") . "/" . ($l9["total"]??"?") . "@" . ($l9["score"]??"?") . "% Providers=" . count($pv["providers"]??[]) . "(" . ($pv["total_models"]??"?") . "M) Git=" . trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l")) . "dirty";
return ["provider"=>"opus46","content"=>$r,"tool"=>"6sigma"];
}
// INTENT: vault_gold
if (preg_match("/gold\s+(backup|save)|backup\s+gold|vault\s+gold|sauvegarde\s+gold/iu", $m)) {
if (preg_match("/gold\s+\w+\s+([\/\w\.\-]+)/iu", $msg, $gm)) {
$p = $gm[1]; if ($p[0] !== "/") $p = "/var/www/html/$p";
if (file_exists($p)) { $g = $p . ".GOLD-" . date("Ymd-His"); copy($p, $g); return ["provider"=>"opus46","content"=>"GOLD: $g (" . filesize($g) . "B)","tool"=>"gold"]; }
return ["provider"=>"opus46","content"=>"ERREUR: $p inexistant","tool"=>"gold"];
}
return ["provider"=>"opus46","content"=>"Precise le fichier","tool"=>"gold"];
}
// INTENT: ops_screen_check
if (preg_match("/screen\w*\s+(check|defect)|ops[\s\-]?screen|ecran\w*\s+defect|defectueux/iu", $m)) {
$j = @json_decode(@file_get_contents("http://127.0.0.1/api/infra-monitor-api.php"), true);
return ["provider"=>"opus46","content"=>"OPS: UP=" . ($j["up"]??"?") . " DOWN=" . ($j["down"]??"?") . " 5xx=" . ($j["error_5xx"]??"?"),"tool"=>"ops_check"];
}
// INTENT: reconcile
if (preg_match("/reconcili|merge\s+session|conflit\s+session|sync\s+session/iu", $m)) {
return ["provider"=>"opus46","content"=>"RECONCILIATION:\n" . trim(@shell_exec("cd /var/www/html && git log --oneline -15 2>&1")) . "\nDirty:" . trim(@shell_exec("cd /var/www/html && git status --short 2>&1 | wc -l")),"tool"=>"reconcile"];
}
// INTENT: playwright_verify
if (preg_match("/playwright\s+verif|verif\w*\s+playwright|visual\s+test/iu", $m)) {
@shell_exec("nohup bash -c 'cd /var/www/html && node api/l99-visual-test.js > /tmp/pw-vis.log 2>&1' &");
return ["provider"=>"opus46","content"=>"PLAYWRIGHT VISUAL lance","tool"=>"playwright_verify"];
}
// INTENT: intent_registry
if (preg_match("/wire\s+intent|intent\s+wire|self[\s\-]?wire|nouvel?\s+intent|intent\s+registry/iu", $m)) {
$ic = trim(@shell_exec("grep -c 'preg_match' /var/www/html/api/wevia-opus-intents.php 2>/dev/null"));
$fc = trim(@shell_exec("grep -c 'preg_match' /var/www/html/api/wevia-fast-path-v3.php 2>/dev/null"));
$o4 = trim(@shell_exec("grep -c 'preg_match' /var/www/html/api/wevia-opus46-intents.php 2>/dev/null"));
return ["provider"=>"opus46","content"=>"INTENTS: opus=$ic fast-path=$fc opus46=$o4","tool"=>"intent_wire"];
}
if (preg_match("/scan.*skills|skills.*scan|inject.*skills|skills.*inject|refresh.*skills|0.*skills/iu", $m)) {
$s=[];$d="/var/www/html/skills/";
foreach(scandir($d) as $e){if($e[0]==".")continue;$full=realpath("$d/$e");if(!$full||!is_dir($full))continue;
foreach(scandir($full) as $x){if($x[0]==".")continue;$s[]=["slug"=>"$e/$x","name"=>pathinfo($x,4),"source"=>$e];}}
$c2="/var/www/html/api/oss-cache.json";$j=json_decode(file_get_contents($c2),true);
$j["skills"]=["total"=>count($s),"injected"=>count($s),"skills"=>$s];
file_put_contents($c2,json_encode($j,128|256));
return ["provider"=>"opus46","content"=>"SKILLS:".count($s),"tool"=>"skills_scan"];
}
if (preg_match("/charge.*(serveur|server)|load.*(average|serveur)|uptime|memoire.*serveur|cpu.*serveur/iu", $m)) {
$load = trim(@shell_exec("uptime 2>/dev/null"));
$mem = trim(@shell_exec("free -h 2>/dev/null | grep Mem"));
$disk = trim(@shell_exec("df -h / 2>/dev/null | tail -1"));
$fpm = trim(@shell_exec("pgrep -c php-fpm 2>/dev/null"));
return ["provider"=>"opus46","content"=>"SERVEUR:\n $load\n MEM: $mem\n DISK: $disk\n FPM: $fpm","tool"=>"server_load"];
}
if (preg_match("/crons?\s+(actif|list|quels|detail)|quels?\s+crons?|list\w*\s+crons?/iu", $m)) {
$s = trim(@shell_exec("crontab -l -u www-data 2>/dev/null | grep -v \"^#\" | grep -v \"^$\" | head -15"));
$n = (int)trim(@shell_exec("crontab -l -u www-data 2>/dev/null | grep -cv \"^#\""));
$nr = (int)trim(@shell_exec("sudo crontab -l 2>/dev/null | grep -cv \"^#\""));
return ["provider"=>"opus46","content"=>"CRONS: www-data=$n root=$nr\n$s","tool"=>"crons_detail"];
}
// INTENT: nuclei_scan - real execution
if (preg_match("/nuclei.*scan|scan.*nuclei|lance.*nuclei|vulnerabilit|vuln.*scan|owasp.*scan/iu", $m)) {
$target = "https://weval-consulting.com";
if (preg_match("/scan\s+(https?:\/\/\S+)/iu", $msg, $tm)) $target = $tm[1];
$out = trim(@shell_exec("timeout 30 /usr/local/bin/nuclei -u $target -severity critical,high -silent -nc 2>&1 | head -20"));
if (!$out) $out = "0 vulnérabilités critical/high détectées";
return ["provider"=>"opus46","content"=>"NUCLEI SCAN $target:\n$out","tool"=>"nuclei_scan"];
}
return null;
}

View File

@@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — Architecture Complète & Plan Scalabilité</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#09090b;--s1:#111113;--s2:#1a1a1f;--s3:#242429;
--acc:#00e5ff;--acc2:#7c3aed;--g:#22c55e;--r:#ef4444;--o:#eab308;--p:#a78bfa;
--coral:#f97066;--teal:#2dd4bf;--blue:#3b82f6;--pink:#f472b6;
--t:#f4f4f5;--dim:#a1a1aa;--dim2:#71717a;
--border:rgba(255,255,255,.06);
--hf:'JetBrains Mono',monospace;--bf:'Outfit',system-ui,sans-serif;
--radius:10px}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--bf);background:var(--bg);color:var(--t);overflow-x:hidden;line-height:1.5}
::selection{background:rgba(0,229,255,.2)}
::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:var(--dim2);border-radius:3px}
.wrap{max-width:1400px;margin:0 auto;padding:20px 24px}
/* HEADER */
.hdr{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--border);margin-bottom:24px}
.hdr h1{font-size:1.4rem;font-weight:700;letter-spacing:-.02em}
.hdr h1 span{color:var(--acc);font-family:var(--hf)}
.hdr .meta{font-size:.7rem;color:var(--dim);font-family:var(--hf)}
.hdr a{color:var(--acc);text-decoration:none;font-size:.75rem;font-family:var(--hf);border:1px solid rgba(0,229,255,.3);padding:4px 12px;border-radius:6px;transition:.2s}
.hdr a:hover{background:rgba(0,229,255,.1)}
/* KPI BAR */
.kpi-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:28px}
.kpi{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;text-align:center}
.kpi .v{font-size:1.3rem;font-weight:700;font-family:var(--hf);color:var(--acc)}
.kpi .l{font-size:.6rem;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
/* SECTIONS */
.sec{margin-bottom:28px}
.sec-title{font-size:.85rem;font-weight:600;color:var(--t);padding:8px 0;border-bottom:1px solid var(--border);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.sec-title .tag{font-size:.55rem;font-family:var(--hf);background:rgba(0,229,255,.12);color:var(--acc);padding:2px 8px;border-radius:4px}
/* GRID */
.g{display:grid;gap:8px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
@media(max-width:900px){.g3,.g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}}
/* CARDS */
.cd{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;transition:.2s;position:relative;overflow:hidden}
.cd:hover{border-color:rgba(255,255,255,.12);transform:translateY(-1px)}
.cd .name{font-size:.75rem;font-weight:600;margin-bottom:2px}
.cd .desc{font-size:.6rem;color:var(--dim);line-height:1.4}
.cd .badge{position:absolute;top:8px;right:8px;font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;font-weight:600}
.cd .dot{width:6px;height:6px;border-radius:50%;display:inline-block;margin-right:4px}
/* Colors */
.cd.purple{border-left:3px solid var(--p)}.cd.purple .name{color:var(--p)}
.cd.coral{border-left:3px solid var(--coral)}.cd.coral .name{color:var(--coral)}
.cd.teal{border-left:3px solid var(--teal)}.cd.teal .name{color:var(--teal)}
.cd.blue{border-left:3px solid var(--blue)}.cd.blue .name{color:var(--blue)}
.cd.green{border-left:3px solid var(--g)}.cd.green .name{color:var(--g)}
.cd.amber{border-left:3px solid var(--o)}.cd.amber .name{color:var(--o)}
.cd.pink{border-left:3px solid var(--pink)}.cd.pink .name{color:var(--pink)}
.cd.red{border-left:3px solid var(--r)}.cd.red .name{color:var(--r)}
.cd.gray{border-left:3px solid var(--dim2)}
.up{background:rgba(34,197,94,.15);color:var(--g)}
.down{background:rgba(239,68,68,.15);color:var(--r)}
.warn{background:rgba(234,179,8,.15);color:var(--o)}
/* PIPELINE */
.pipeline{display:flex;align-items:center;gap:0;overflow-x:auto;padding:4px 0}
.pipeline .step{background:var(--s2);border:1px solid var(--border);padding:8px 14px;font-size:.65rem;font-weight:500;white-space:nowrap;position:relative}
.pipeline .step:first-child{border-radius:var(--radius) 0 0 var(--radius)}
.pipeline .step:last-child{border-radius:0 var(--radius) var(--radius) 0}
.pipeline .arrow{color:var(--dim2);font-size:.7rem;margin:0 -1px;z-index:1}
/* PLAN */
.plan-item{display:flex;gap:10px;padding:8px 12px;background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:6px;align-items:flex-start}
.plan-item .num{font-family:var(--hf);font-size:.7rem;font-weight:700;color:var(--acc);min-width:20px}
.plan-item .txt{font-size:.68rem;color:var(--dim);line-height:1.5}
.plan-item .txt strong{color:var(--t);font-weight:600}
.plan-item .pri{font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;margin-left:auto;white-space:nowrap}
.pri.p0{background:rgba(239,68,68,.15);color:var(--r)}
.pri.p1{background:rgba(234,179,8,.15);color:var(--o)}
.pri.p2{background:rgba(59,130,246,.15);color:var(--blue)}
/* ANIM */
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sec{animation:fadeIn .4s ease both}
.sec:nth-child(2){animation-delay:.05s}
.sec:nth-child(3){animation-delay:.1s}
.sec:nth-child(4){animation-delay:.15s}
.sec:nth-child(5){animation-delay:.2s}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr">
<h1><span>WEVAL</span> Architecture Map</h1>
<div style="text-align:right">
<div class="meta">14 avril 2026 · Session Opus</div>
<a href="/architecture.html">Control Center</a>
</div>
</div>
<!-- KPIs -->
<div class="kpi-bar">
<div class="kpi"><div class="v">346</div><div class="l">Tools</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">13</div><div class="l">Providers IA</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">141K</div><div class="l">HCPs Ethica</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">150+</div><div class="l">Écrans Arsenal</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">0€</div><div class="l">Coût IA</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">3.5M</div><div class="l">Pipeline MAD</div></div>
<div class="kpi"><div class="v" style="color:var(--pink)">870</div><div class="l">Agents</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">150/152</div><div class="l">NonReg</div></div>
</div>
<!-- ═══ SECTION 1: APPS FRONTEND ═══ -->
<div class="sec">
<div class="sec-title">Applications frontend <span class="tag">22 apps</span></div>
<div class="g4">
<div class="cd purple"><div class="name">wevia.html</div><div class="desc">Chatbot IA public · Cloudflare-AI · SSE streaming</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-master.html</div><div class="desc">Master AI · 346 tools · FastPath · Resolver v8</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-cortex.html</div><div class="desc">Cortex v2.1 · Multi-agent · 669 agents</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-arena.html</div><div class="desc">Arena multi-LLM · A/B test providers</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">growth-engine-v2.html</div><div class="desc">GE v3 · 8 verticaux · Pipeline 3.5M MAD</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">blade-ai.html</div><div class="desc">Blade IA GODMODE 10/10 · 421L 30KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">office-workflow.php</div><div class="desc">CRM + process automation · 65KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">architecture.html</div><div class="desc">Control Center · scan LIVE infra</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">Ethica Dashboard</div><div class="desc">6 modules · HCP manager · consent · SMS · drill</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">l99-saas.html</div><div class="desc">L99 SaaS · 1113 files indexed</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">agents-archi.html</div><div class="desc">3D agents visualization · 94KB</div><div class="badge warn">301</div></div>
<div class="cd green"><div class="name">director-center.html</div><div class="desc">Director + Monitoring Kuma</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEDROID</div><div class="desc">Factory IA · callCloud cascade</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">OpenClaw</div><div class="desc">Code agent · terminal web</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEVCODE</div><div class="desc">IDE souverain · Monaco editor</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">Nuclei</div><div class="desc">Security scanner · vuln detection</div><div class="badge warn">IDLE</div></div>
<div class="cd blue"><div class="name">WEVADS IA (ADX)</div><div class="desc">Email pipeline · 6.6M contacts · Brain Engine</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">WEVIA Life</div><div class="desc">Session sync · chat history · wevialife-sync.php</div><div class="badge up">CRON</div></div>
<div class="cd blue"><div class="name">consent.wevup.app</div><div class="desc">RGPD landing · optin/optout tokens</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">Paperclip</div><div class="desc">870 agents · 6 projets actifs · 2484 skills</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">enterprise-model.html</div><div class="desc">669 agents · 22 depts · 3D rooms</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 2: CASCADE IA SOUVERAINE ═══ -->
<div class="sec">
<div class="sec-title">Cascade IA souveraine <span class="tag">13 providers · 0€</span></div>
<div style="background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;margin-bottom:10px">
<div style="font-size:.7rem;font-family:var(--hf);color:var(--acc);margin-bottom:8px">sovereign-api.py :4000 — auto-cascade · primary: Cerebras-fast</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 1 — Ultra-rapide (&lt;0.5s)</div>
<div class="g4" style="margin-bottom:8px">
<div class="cd coral"><div class="name">Cerebras-fast</div><div class="desc">llama-3.3-70b · 0.25s · PRIMARY</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cerebras-think</div><div class="desc">Qwen3-235B · Chain-of-Thought</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Groq</div><div class="desc">llama-3.1-8b-instant · 0.23s</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cloudflare AI</div><div class="desc">Workers AI · 10K req/j free GPU</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 2 — Rapide (&lt;2s)</div>
<div class="g5" style="margin-bottom:8px">
<div class="cd amber"><div class="name">Gemini</div><div class="desc">2.0-flash free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">SambaNova</div><div class="desc">DeepSeek-V3.2</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">NVIDIA NIM</div><div class="desc">Llama 3.1 free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">Mistral</div><div class="desc">open-nemo free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">GitHub Models</div><div class="desc">API free tier</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 3 — Fallback</div>
<div class="g4">
<div class="cd gray"><div class="name">HF Space</div><div class="desc">weval-brain-v4 fine-tuné</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">HF Router</div><div class="desc">Qwen2.5-72B serverless</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">OpenRouter</div><div class="desc">Free tier multi-model</div><div class="badge up">UP</div></div>
<div class="cd red"><div class="name">Ollama (LOCAL)</div><div class="desc">DISABLED · RAM killer · 6 modèles</div><div class="badge down">OFF</div></div>
</div>
</div>
</div>
<!-- ═══ SECTION 3: GPU FREE COMPUTE ═══ -->
<div class="sec">
<div class="sec-title">GPU free compute <span class="tag">fine-tune + inference</span></div>
<div class="g3">
<div class="cd blue"><div class="name">Kaggle T4/P100</div><div class="desc">30h/sem GPU gratuit · fine-tune LoRA · notebooks configurés</div><div class="badge up">READY</div></div>
<div class="cd blue"><div class="name">HF Space vLLM</div><div class="desc">yace222/weval-vllm · cpu-basic (GPU=PRO) · commit 5b4b422</div><div class="badge warn">CPU</div></div>
<div class="cd blue"><div class="name">Google Colab</div><div class="desc">T4 free 12h/session · notebooks prêts</div><div class="badge up">READY</div></div>
<div class="cd teal"><div class="name">CF Workers AI</div><div class="desc">10K req/jour · GPU edge Cloudflare · Llama 3.1</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">HF fine-tune</div><div class="desc">yace222/weval-brain-v4 · LoRA adapter · Qwen2.5</div><div class="badge up">TRAINED</div></div>
<div class="cd teal"><div class="name">Render / Railway</div><div class="desc">Free tier configuré · backup deploy</div><div class="badge warn">STANDBY</div></div>
</div>
</div>
<!-- ═══ SECTION 4: ETHICA B2B ═══ -->
<div class="sec">
<div class="sec-title">Ethica B2B Pharma <span class="tag">141K HCPs</span></div>
<div class="kpi-bar" style="grid-template-columns:repeat(6,1fr);margin-bottom:12px">
<div class="kpi"><div class="v" style="color:var(--g)">131,214</div><div class="l">HCPs total</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">109,692</div><div class="l">Emails</div></div>
<div class="kpi"><div class="v" style="color:var(--blue)">121,940</div><div class="l">Téléphones</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">34</div><div class="l">Spécialités</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">DZ 88K</div><div class="l">Algérie</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">MA+TN 36K</div><div class="l">Maroc + Tunisie</div></div>
</div>
<div class="pipeline" style="margin-bottom:10px">
<div class="step" style="border-left:3px solid var(--g)">Scrapers (CNAM+DabaDoc+Rich)</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--teal)">Validator DNS/MX</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--blue)">MA Boost 4x/j</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--o)">Consent wevup.app</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--coral)">Campagnes O365+PMTA</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--p)">Tracking open.php</div>
</div>
<div class="g3">
<div class="cd green"><div class="name">10 senders O365</div><div class="desc">3 tenants Graph API · 97% inbox</div></div>
<div class="cd green"><div class="name">10 SMS providers</div><div class="desc">130K SMS/jour capacité</div></div>
<div class="cd green"><div class="name">WhatsApp Meta WA</div><div class="desc">Business API configuré</div></div>
</div>
</div>
<!-- ═══ SECTION 5: INFRA SERVEURS ═══ -->
<div class="sec">
<div class="sec-title">Infrastructure serveurs <span class="tag">2 serveurs + 4 ECS</span></div>
<div class="g2" style="margin-bottom:8px">
<div class="cd blue" style="padding:14px">
<div class="name" style="font-size:.85rem">S204 — 204.168.152.13</div>
<div class="desc" style="margin-bottom:6px">10.1.0.2 · MTA + WEVIA + Ethica · RAM 32GB · Disk 67%</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> nginx :443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Apache :8443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PHP 8.4 FPM</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Docker (10)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sovereign :4000</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--r)">●</span> Ollama OFF</div>
</div>
</div>
<div class="cd teal" style="padding:14px">
<div class="name" style="font-size:.85rem">S95 — 95.216.167.89</div>
<div class="desc" style="margin-bottom:6px">10.1.0.3 · Hetzner · WEVADS prod · Arsenal · Sentinel</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PG :5432 (6.6M)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sentinel :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Arsenal :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PMTA :25</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> KumoMTA :587</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> ADX :5821</div>
</div>
</div>
</div>
<div class="cd amber" style="padding:10px">
<div class="name" style="font-size:.8rem">4 ECS Huawei — PMTA 4.5r8</div>
<div class="g4" style="margin-top:6px;gap:4px">
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_6</span><br><span style="color:var(--dim)">110.239.84.121</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_7</span><br><span style="color:var(--dim)">110.239.65.64</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_8</span><br><span style="color:var(--dim)">182.160.55.107</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_9</span><br><span style="color:var(--dim)">110.239.86.68</span></div>
</div>
</div>
</div>
<!-- ═══ SECTION 6: PIPELINE E2E ═══ -->
<div class="sec">
<div class="sec-title">Pipeline E2E email marketing <span class="tag">PULL model</span></div>
<div class="pipeline">
<div class="step" style="background:var(--s2);border-left:3px solid var(--g)">Brain Engine<br><span style="font-size:.5rem;color:var(--dim)">646 configs · 9 winners</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--blue)">Send O365/PMTA<br><span style="font-size:.5rem;color:var(--dim)">97% inbox</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--teal)">Open (open.php)<br><span style="font-size:.5rem;color:var(--dim)">S204 tracking</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--o)">Click<br><span style="font-size:.5rem;color:var(--dim)">552 links actifs</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--coral)">Conversion<br><span style="font-size:.5rem;color:var(--dim)">CAKE/Everflow</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--p)">PULL collector<br><span style="font-size:.5rem;color:var(--dim)">cron 30min</span></div>
</div>
</div>
<!-- ═══ SECTION 7: AGENTS + SERVICES ═══ -->
<div class="sec">
<div class="sec-title">Agents + services internes <span class="tag">Docker + systemd</span></div>
<div class="g4">
<div class="cd pink"><div class="name">Paperclip</div><div class="desc">870 agents · 2484 skills · 6 projets actifs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">Qdrant :6333</div><div class="desc">5 collections · 16K vecteurs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">SearXNG</div><div class="desc">Moteur de recherche privé</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Listmonk</div><div class="desc">Email marketing self-hosted</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Uptime Kuma</div><div class="desc">Monitoring 24/7</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Wiki (1194)</div><div class="desc">JSON knowledge base</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Vault GOLD (424)</div><div class="desc">Backup auto + checksums</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 8: CLOUDFLARE + DNS ═══ -->
<div class="sec">
<div class="sec-title">Cloudflare + DNS <span class="tag">41 comptes · 16 zones</span></div>
<div class="g4">
<div class="cd amber"><div class="name">weval-consulting.com</div><div class="desc">Site principal + API + WEVIA</div></div>
<div class="cd amber"><div class="name">wevup.app</div><div class="desc">consent.wevup.app + DNS Hetzner</div></div>
<div class="cd amber"><div class="name">culturellemejean.charity</div><div class="desc">Tracking domain · open.php</div></div>
<div class="cd amber"><div class="name">41 comptes CF Brahim</div><div class="desc">Rotation + multi-zone</div></div>
</div>
</div>
<!-- ═══ SECTION 9: PARTENARIATS ═══ -->
<div class="sec">
<div class="sec-title">Partenariats actifs <span class="tag">4 deals</span></div>
<div class="g4">
<div class="cd purple"><div class="name">Vistex (SAP)</div><div class="desc">Maghreb retail/pharma · litige lead protection Section 6.c.i</div></div>
<div class="cd purple"><div class="name">Scaleway / Arrow</div><div class="desc">ArrowSphere onboarding · cloud MSP</div></div>
<div class="cd purple"><div class="name">Huawei Cloud</div><div class="desc">4 ECS PMTA · litige billing actif</div></div>
<div class="cd purple"><div class="name">Ethica (Kaouther)</div><div class="desc">HCP Maghreb 2027 · email prêt</div></div>
</div>
</div>
<!-- ═══ SECTION 10: PLAN D'ACTION OPTIMISATION + SCALABILITÉ ═══ -->
<div class="sec">
<div class="sec-title">Plan d'action — optimisation + scalabilité <span class="tag">15 actions</span></div>
<div class="plan-item"><div class="num">01</div><div class="txt"><strong>HF Space GPU upgrade</strong> — passer yace222/weval-vllm de cpu-basic à GPU free (T4) quand HF PRO dispo. Objectif : inference vLLM souveraine 0€</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">02</div><div class="txt"><strong>Kaggle fine-tune pipeline</strong> — automatiser le fine-tune weval-brain-v5 sur Kaggle T4 avec les données wiki+KB (1194 entries). Objectif : modèle souverain amélioré</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">03</div><div class="txt"><strong>Ethica gap 21K emails</strong> — enrichir les 21,522 HCPs sans email via scrapers CNAM v3 + SearXNG + DabaDoc deep. Objectif : 120K+ emails</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">04</div><div class="txt"><strong>Campagne consent pilot</strong> — lancer pilot 500 DZ + 500 MA après validation Kaouther. Safety lock actif. Objectif : premiers consentements réels</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">05</div><div class="txt"><strong>Ollama selective restart</strong> — réactiver Ollama avec 1 seul modèle léger (qwen3:4b, 5GB) sur schedule cron (ON 8h-20h, OFF nuit). Objectif : inference locale sans crash RAM</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">06</div><div class="txt"><strong>WEVIA Life auto-sync</strong> — wevialife-sync.php enrichi avec session context + conversation memory → Qdrant. Objectif : mémoire persistante cross-session</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">07</div><div class="txt"><strong>NonReg 152/152</strong> — investiguer les 2 tests skip. Probablement dépendance S151 décommissionné. Objectif : 100% pass</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">08</div><div class="txt"><strong>S95 disk cleanup</strong> — disk à 85%. Purger logs, Docker images, old backups. Objectif : &lt;70%</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">09</div><div class="txt"><strong>GitHub PAT renouvellement</strong> — le token expire bientôt. Renouveler manuellement via github.com/settings/tokens</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">10</div><div class="txt"><strong>Scaleway 5 POC</strong> — déployer les 5 POC cloud (ArrowSphere). Objectif : 240K MAD pipeline</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">11</div><div class="txt"><strong>Multi-region PMTA</strong> — ajouter 2 ECS Europe (Hetzner) pour améliorer inbox EU. Objectif : 99% inbox Europe</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">12</div><div class="txt"><strong>Whisper.cpp local</strong> — réactiver voice-to-text souverain sur S204 CPU. Objectif : transcription audio WEVIA</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">13</div><div class="txt"><strong>DeerFlow réactivation</strong> — restart quand RAM stabilisée. Objectif : workflow automation</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">14</div><div class="txt"><strong>S204 RAM upgrade</strong> — passer de 16GB à 32GB pour supporter Ollama + Docker + FPM sans crash. Objectif : stabilité définitive</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">15</div><div class="txt"><strong>Sovereign API v4</strong> — ajouter Llama 4 Scout (Groq), DeepSeek-R1 (SambaNova), Qwen3-235B-think (Cerebras). Objectif : 15/15 providers</div><div class="pri p2">P2</div></div>
</div>
<!-- FOOTER -->
<div style="text-align:center;padding:20px 0;border-top:1px solid var(--border);margin-top:20px">
<div style="font-size:.65rem;color:var(--dim)">WEVAL Consulting · Casablanca · 14 avril 2026</div>
<div style="font-size:.6rem;color:var(--dim2);margin-top:4px">Session Opus directeur de projet · 346 tools · 13 providers · 141K HCPs · 0€ IA</div>
</div>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body>
</html>

View File

@@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — Architecture Complète & Plan Scalabilité</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#09090b;--s1:#111113;--s2:#1a1a1f;--s3:#242429;
--acc:#00e5ff;--acc2:#7c3aed;--g:#22c55e;--r:#ef4444;--o:#eab308;--p:#a78bfa;
--coral:#f97066;--teal:#2dd4bf;--blue:#3b82f6;--pink:#f472b6;
--t:#f4f4f5;--dim:#a1a1aa;--dim2:#71717a;
--border:rgba(255,255,255,.06);
--hf:'JetBrains Mono',monospace;--bf:'Outfit',system-ui,sans-serif;
--radius:10px}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--bf);background:var(--bg);color:var(--t);overflow-x:hidden;line-height:1.5}
::selection{background:rgba(0,229,255,.2)}
::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:var(--dim2);border-radius:3px}
.wrap{max-width:1400px;margin:0 auto;padding:20px 24px}
/* HEADER */
.hdr{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--border);margin-bottom:24px}
.hdr h1{font-size:1.4rem;font-weight:700;letter-spacing:-.02em}
.hdr h1 span{color:var(--acc);font-family:var(--hf)}
.hdr .meta{font-size:.7rem;color:var(--dim);font-family:var(--hf)}
.hdr a{color:var(--acc);text-decoration:none;font-size:.75rem;font-family:var(--hf);border:1px solid rgba(0,229,255,.3);padding:4px 12px;border-radius:6px;transition:.2s}
.hdr a:hover{background:rgba(0,229,255,.1)}
/* KPI BAR */
.kpi-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:28px}
.kpi{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;text-align:center}
.kpi .v{font-size:1.3rem;font-weight:700;font-family:var(--hf);color:var(--acc)}
.kpi .l{font-size:.6rem;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
/* SECTIONS */
.sec{margin-bottom:28px}
.sec-title{font-size:.85rem;font-weight:600;color:var(--t);padding:8px 0;border-bottom:1px solid var(--border);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.sec-title .tag{font-size:.55rem;font-family:var(--hf);background:rgba(0,229,255,.12);color:var(--acc);padding:2px 8px;border-radius:4px}
/* GRID */
.g{display:grid;gap:8px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
@media(max-width:900px){.g3,.g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}}
/* CARDS */
.cd{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;transition:.2s;position:relative;overflow:hidden}
.cd:hover{border-color:rgba(255,255,255,.12);transform:translateY(-1px)}
.cd .name{font-size:.75rem;font-weight:600;margin-bottom:2px}
.cd .desc{font-size:.6rem;color:var(--dim);line-height:1.4}
.cd .badge{position:absolute;top:8px;right:8px;font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;font-weight:600}
.cd .dot{width:6px;height:6px;border-radius:50%;display:inline-block;margin-right:4px}
/* Colors */
.cd.purple{border-left:3px solid var(--p)}.cd.purple .name{color:var(--p)}
.cd.coral{border-left:3px solid var(--coral)}.cd.coral .name{color:var(--coral)}
.cd.teal{border-left:3px solid var(--teal)}.cd.teal .name{color:var(--teal)}
.cd.blue{border-left:3px solid var(--blue)}.cd.blue .name{color:var(--blue)}
.cd.green{border-left:3px solid var(--g)}.cd.green .name{color:var(--g)}
.cd.amber{border-left:3px solid var(--o)}.cd.amber .name{color:var(--o)}
.cd.pink{border-left:3px solid var(--pink)}.cd.pink .name{color:var(--pink)}
.cd.red{border-left:3px solid var(--r)}.cd.red .name{color:var(--r)}
.cd.gray{border-left:3px solid var(--dim2)}
.up{background:rgba(34,197,94,.15);color:var(--g)}
.down{background:rgba(239,68,68,.15);color:var(--r)}
.warn{background:rgba(234,179,8,.15);color:var(--o)}
/* PIPELINE */
.pipeline{display:flex;align-items:center;gap:0;overflow-x:auto;padding:4px 0}
.pipeline .step{background:var(--s2);border:1px solid var(--border);padding:8px 14px;font-size:.65rem;font-weight:500;white-space:nowrap;position:relative}
.pipeline .step:first-child{border-radius:var(--radius) 0 0 var(--radius)}
.pipeline .step:last-child{border-radius:0 var(--radius) var(--radius) 0}
.pipeline .arrow{color:var(--dim2);font-size:.7rem;margin:0 -1px;z-index:1}
/* PLAN */
.plan-item{display:flex;gap:10px;padding:8px 12px;background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:6px;align-items:flex-start}
.plan-item .num{font-family:var(--hf);font-size:.7rem;font-weight:700;color:var(--acc);min-width:20px}
.plan-item .txt{font-size:.68rem;color:var(--dim);line-height:1.5}
.plan-item .txt strong{color:var(--t);font-weight:600}
.plan-item .pri{font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;margin-left:auto;white-space:nowrap}
.pri.p0{background:rgba(239,68,68,.15);color:var(--r)}
.pri.p1{background:rgba(234,179,8,.15);color:var(--o)}
.pri.p2{background:rgba(59,130,246,.15);color:var(--blue)}
/* ANIM */
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sec{animation:fadeIn .4s ease both}
.sec:nth-child(2){animation-delay:.05s}
.sec:nth-child(3){animation-delay:.1s}
.sec:nth-child(4){animation-delay:.15s}
.sec:nth-child(5){animation-delay:.2s}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr">
<h1><span>WEVAL</span> Architecture Map</h1>
<div style="text-align:right">
<div class="meta">14 avril 2026 · Session Opus</div>
<a href="/architecture.html">Control Center</a>
</div>
</div>
<!-- KPIs -->
<div class="kpi-bar">
<div class="kpi"><div class="v">346</div><div class="l">Tools</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">13</div><div class="l">Providers IA</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">141K</div><div class="l">HCPs Ethica</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">150+</div><div class="l">Écrans Arsenal</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">0€</div><div class="l">Coût IA</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">3.5M</div><div class="l">Pipeline MAD</div></div>
<div class="kpi"><div class="v" style="color:var(--pink)">870</div><div class="l">Agents</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">150/152</div><div class="l">NonReg</div></div>
</div>
<!-- ═══ SECTION 1: APPS FRONTEND ═══ -->
<div class="sec">
<div class="sec-title">Applications frontend <span class="tag">22 apps</span></div>
<div class="g4">
<div class="cd purple"><div class="name">wevia.html</div><div class="desc">Chatbot IA public · Cloudflare-AI · SSE streaming</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-master.html</div><div class="desc">Master AI · 346 tools · FastPath · Resolver v8</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-cortex.html</div><div class="desc">Cortex v2.1 · Multi-agent · 669 agents</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-arena.html</div><div class="desc">Arena multi-LLM · A/B test providers</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">growth-engine-v2.html</div><div class="desc">GE v3 · 8 verticaux · Pipeline 3.5M MAD</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">blade-ai.html</div><div class="desc">Blade IA GODMODE 10/10 · 421L 30KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">office-workflow.php</div><div class="desc">CRM + process automation · 65KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">architecture.html</div><div class="desc">Control Center · scan LIVE infra</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">Ethica Dashboard</div><div class="desc">6 modules · HCP manager · consent · SMS · drill</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">l99-saas.html</div><div class="desc">L99 SaaS · 1113 files indexed</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">agents-archi.html</div><div class="desc">3D agents visualization · 94KB</div><div class="badge warn">301</div></div>
<div class="cd green"><div class="name">director-center.html</div><div class="desc">Director + Monitoring Kuma</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEDROID</div><div class="desc">Factory IA · callCloud cascade</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">OpenClaw</div><div class="desc">Code agent · terminal web</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEVCODE</div><div class="desc">IDE souverain · Monaco editor</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">Nuclei</div><div class="desc">Security scanner · vuln detection</div><div class="badge warn">IDLE</div></div>
<div class="cd blue"><div class="name">WEVADS IA (ADX)</div><div class="desc">Email pipeline · 6.6M contacts · Brain Engine</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">WEVIA Life</div><div class="desc">Session sync · chat history · wevialife-sync.php</div><div class="badge up">CRON</div></div>
<div class="cd blue"><div class="name">consent.wevup.app</div><div class="desc">RGPD landing · optin/optout tokens</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">Paperclip</div><div class="desc">870 agents · 6 projets actifs · 2484 skills</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">enterprise-model.html</div><div class="desc">669 agents · 22 depts · 3D rooms</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 2: CASCADE IA SOUVERAINE ═══ -->
<div class="sec">
<div class="sec-title">Cascade IA souveraine <span class="tag">13 providers · 0€</span></div>
<div style="background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;margin-bottom:10px">
<div style="font-size:.7rem;font-family:var(--hf);color:var(--acc);margin-bottom:8px">sovereign-api.py :4000 — auto-cascade · primary: Cerebras-fast</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 1 — Ultra-rapide (&lt;0.5s)</div>
<div class="g4" style="margin-bottom:8px">
<div class="cd coral"><div class="name">Cerebras-fast</div><div class="desc">llama-3.3-70b · 0.25s · PRIMARY</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cerebras-think</div><div class="desc">Qwen3-235B · Chain-of-Thought</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Groq</div><div class="desc">llama-3.1-8b-instant · 0.23s</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cloudflare AI</div><div class="desc">Workers AI · 10K req/j free GPU</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 2 — Rapide (&lt;2s)</div>
<div class="g5" style="margin-bottom:8px">
<div class="cd amber"><div class="name">Gemini</div><div class="desc">2.0-flash free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">SambaNova</div><div class="desc">DeepSeek-V3.2</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">NVIDIA NIM</div><div class="desc">Llama 3.1 free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">Mistral</div><div class="desc">open-nemo free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">GitHub Models</div><div class="desc">API free tier</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 3 — Fallback</div>
<div class="g4">
<div class="cd gray"><div class="name">HF Space</div><div class="desc">weval-brain-v4 fine-tuné</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">HF Router</div><div class="desc">Qwen2.5-72B serverless</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">OpenRouter</div><div class="desc">Free tier multi-model</div><div class="badge up">UP</div></div>
<div class="cd red"><div class="name">Ollama (LOCAL)</div><div class="desc">DISABLED · RAM killer · 6 modèles</div><div class="badge down">OFF</div></div>
</div>
</div>
</div>
<!-- ═══ SECTION 3: GPU FREE COMPUTE ═══ -->
<div class="sec">
<div class="sec-title">GPU free compute <span class="tag">fine-tune + inference</span></div>
<div class="g3">
<div class="cd blue"><div class="name">Kaggle T4/P100</div><div class="desc">30h/sem GPU gratuit · fine-tune LoRA · notebooks configurés</div><div class="badge up">READY</div></div>
<div class="cd blue"><div class="name">HF Space vLLM</div><div class="desc">yace222/weval-vllm · cpu-basic (GPU=PRO) · commit 5b4b422</div><div class="badge warn">CPU</div></div>
<div class="cd blue"><div class="name">Google Colab</div><div class="desc">T4 free 12h/session · notebooks prêts</div><div class="badge up">READY</div></div>
<div class="cd teal"><div class="name">CF Workers AI</div><div class="desc">10K req/jour · GPU edge Cloudflare · Llama 3.1</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">HF fine-tune</div><div class="desc">yace222/weval-brain-v4 · LoRA adapter · Qwen2.5</div><div class="badge up">TRAINED</div></div>
<div class="cd teal"><div class="name">Render / Railway</div><div class="desc">Free tier configuré · backup deploy</div><div class="badge warn">STANDBY</div></div>
</div>
</div>
<!-- ═══ SECTION 4: ETHICA B2B ═══ -->
<div class="sec">
<div class="sec-title">Ethica B2B Pharma <span class="tag">141K HCPs</span></div>
<div class="kpi-bar" style="grid-template-columns:repeat(6,1fr);margin-bottom:12px">
<div class="kpi"><div class="v" style="color:var(--g)">131,214</div><div class="l">HCPs total</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">109,692</div><div class="l">Emails</div></div>
<div class="kpi"><div class="v" style="color:var(--blue)">121,940</div><div class="l">Téléphones</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">34</div><div class="l">Spécialités</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">DZ 88K</div><div class="l">Algérie</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">MA+TN 36K</div><div class="l">Maroc + Tunisie</div></div>
</div>
<div class="pipeline" style="margin-bottom:10px">
<div class="step" style="border-left:3px solid var(--g)">Scrapers (CNAM+DabaDoc+Rich)</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--teal)">Validator DNS/MX</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--blue)">MA Boost 4x/j</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--o)">Consent wevup.app</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--coral)">Campagnes O365+PMTA</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--p)">Tracking open.php</div>
</div>
<div class="g3">
<div class="cd green"><div class="name">10 senders O365</div><div class="desc">3 tenants Graph API · 97% inbox</div></div>
<div class="cd green"><div class="name">10 SMS providers</div><div class="desc">130K SMS/jour capacité</div></div>
<div class="cd green"><div class="name">WhatsApp Meta WA</div><div class="desc">Business API configuré</div></div>
</div>
</div>
<!-- ═══ SECTION 5: INFRA SERVEURS ═══ -->
<div class="sec">
<div class="sec-title">Infrastructure serveurs <span class="tag">2 serveurs + 4 ECS</span></div>
<div class="g2" style="margin-bottom:8px">
<div class="cd blue" style="padding:14px">
<div class="name" style="font-size:.85rem">S204 — 204.168.152.13</div>
<div class="desc" style="margin-bottom:6px">10.1.0.2 · MTA + WEVIA + Ethica · RAM 32GB · Disk 67%</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> nginx :443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Apache :8443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PHP 8.4 FPM</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Docker (10)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sovereign :4000</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--r)">●</span> Ollama OFF</div>
</div>
</div>
<div class="cd teal" style="padding:14px">
<div class="name" style="font-size:.85rem">S95 — 95.216.167.89</div>
<div class="desc" style="margin-bottom:6px">10.1.0.3 · Hetzner · WEVADS prod · Arsenal · Sentinel</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PG :5432 (6.6M)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sentinel :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Arsenal :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PMTA :25</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> KumoMTA :587</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> ADX :5821</div>
</div>
</div>
</div>
<div class="cd amber" style="padding:10px">
<div class="name" style="font-size:.8rem">4 ECS Huawei — PMTA 4.5r8</div>
<div class="g4" style="margin-top:6px;gap:4px">
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_6</span><br><span style="color:var(--dim)">110.239.84.121</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_7</span><br><span style="color:var(--dim)">110.239.65.64</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_8</span><br><span style="color:var(--dim)">182.160.55.107</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_9</span><br><span style="color:var(--dim)">110.239.86.68</span></div>
</div>
</div>
</div>
<!-- ═══ SECTION 6: PIPELINE E2E ═══ -->
<div class="sec">
<div class="sec-title">Pipeline E2E email marketing <span class="tag">PULL model</span></div>
<div class="pipeline">
<div class="step" style="background:var(--s2);border-left:3px solid var(--g)">Brain Engine<br><span style="font-size:.5rem;color:var(--dim)">646 configs · 9 winners</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--blue)">Send O365/PMTA<br><span style="font-size:.5rem;color:var(--dim)">97% inbox</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--teal)">Open (open.php)<br><span style="font-size:.5rem;color:var(--dim)">S204 tracking</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--o)">Click<br><span style="font-size:.5rem;color:var(--dim)">552 links actifs</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--coral)">Conversion<br><span style="font-size:.5rem;color:var(--dim)">CAKE/Everflow</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--p)">PULL collector<br><span style="font-size:.5rem;color:var(--dim)">cron 30min</span></div>
</div>
</div>
<!-- ═══ SECTION 7: AGENTS + SERVICES ═══ -->
<div class="sec">
<div class="sec-title">Agents + services internes <span class="tag">Docker + systemd</span></div>
<div class="g4">
<div class="cd pink"><div class="name">Paperclip</div><div class="desc">870 agents · 2484 skills · 6 projets actifs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">Qdrant :6333</div><div class="desc">5 collections · 16K vecteurs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">SearXNG</div><div class="desc">Moteur de recherche privé</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Listmonk</div><div class="desc">Email marketing self-hosted</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Uptime Kuma</div><div class="desc">Monitoring 24/7</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Wiki (1194)</div><div class="desc">JSON knowledge base</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Vault GOLD (424)</div><div class="desc">Backup auto + checksums</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 8: CLOUDFLARE + DNS ═══ -->
<div class="sec">
<div class="sec-title">Cloudflare + DNS <span class="tag">41 comptes · 16 zones</span></div>
<div class="g4">
<div class="cd amber"><div class="name">weval-consulting.com</div><div class="desc">Site principal + API + WEVIA</div></div>
<div class="cd amber"><div class="name">wevup.app</div><div class="desc">consent.wevup.app + DNS Hetzner</div></div>
<div class="cd amber"><div class="name">culturellemejean.charity</div><div class="desc">Tracking domain · open.php</div></div>
<div class="cd amber"><div class="name">41 comptes CF Brahim</div><div class="desc">Rotation + multi-zone</div></div>
</div>
</div>
<!-- ═══ SECTION 9: PARTENARIATS ═══ -->
<div class="sec">
<div class="sec-title">Partenariats actifs <span class="tag">4 deals</span></div>
<div class="g4">
<div class="cd purple"><div class="name">Vistex (SAP)</div><div class="desc">Maghreb retail/pharma · litige lead protection Section 6.c.i</div></div>
<div class="cd purple"><div class="name">Scaleway / Arrow</div><div class="desc">ArrowSphere onboarding · cloud MSP</div></div>
<div class="cd purple"><div class="name">Huawei Cloud</div><div class="desc">4 ECS PMTA · litige billing actif</div></div>
<div class="cd purple"><div class="name">Ethica (Kaouther)</div><div class="desc">HCP Maghreb 2027 · email prêt</div></div>
</div>
</div>
<!-- ═══ SECTION 10: PLAN D'ACTION OPTIMISATION + SCALABILITÉ ═══ -->
<div class="sec">
<div class="sec-title">Plan d'action — optimisation + scalabilité <span class="tag">15 actions</span></div>
<div class="plan-item"><div class="num">01</div><div class="txt"><strong>HF Space GPU upgrade</strong> — passer yace222/weval-vllm de cpu-basic à GPU free (T4) quand HF PRO dispo. Objectif : inference vLLM souveraine 0€</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">02</div><div class="txt"><strong>Kaggle fine-tune pipeline</strong> — automatiser le fine-tune weval-brain-v5 sur Kaggle T4 avec les données wiki+KB (1194 entries). Objectif : modèle souverain amélioré</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">03</div><div class="txt"><strong>Ethica gap 21K emails</strong> — enrichir les 21,522 HCPs sans email via scrapers CNAM v3 + SearXNG + DabaDoc deep. Objectif : 120K+ emails</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">04</div><div class="txt"><strong>Campagne consent pilot</strong> — lancer pilot 500 DZ + 500 MA après validation Kaouther. Safety lock actif. Objectif : premiers consentements réels</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">05</div><div class="txt"><strong>Ollama selective restart</strong> — réactiver Ollama avec 1 seul modèle léger (qwen3:4b, 5GB) sur schedule cron (ON 8h-20h, OFF nuit). Objectif : inference locale sans crash RAM</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">06</div><div class="txt"><strong>WEVIA Life auto-sync</strong> — wevialife-sync.php enrichi avec session context + conversation memory → Qdrant. Objectif : mémoire persistante cross-session</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">07</div><div class="txt"><strong>NonReg 152/152</strong> — investiguer les 2 tests skip. Probablement dépendance S151 décommissionné. Objectif : 100% pass</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">08</div><div class="txt"><strong>S95 disk cleanup</strong> — disk à 85%. Purger logs, Docker images, old backups. Objectif : &lt;70%</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">09</div><div class="txt"><strong>GitHub PAT renouvellement</strong> — le token expire bientôt. Renouveler manuellement via github.com/settings/tokens</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">10</div><div class="txt"><strong>Scaleway 5 POC</strong> — déployer les 5 POC cloud (ArrowSphere). Objectif : 240K MAD pipeline</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">11</div><div class="txt"><strong>Multi-region PMTA</strong> — ajouter 2 ECS Europe (Hetzner) pour améliorer inbox EU. Objectif : 99% inbox Europe</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">12</div><div class="txt"><strong>Whisper.cpp local</strong> — réactiver voice-to-text souverain sur S204 CPU. Objectif : transcription audio WEVIA</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">13</div><div class="txt"><strong>DeerFlow réactivation</strong> — restart quand RAM stabilisée. Objectif : workflow automation</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">14</div><div class="txt"><strong>S204 RAM upgrade</strong> — passer de 16GB à 32GB pour supporter Ollama + Docker + FPM sans crash. Objectif : stabilité définitive</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">15</div><div class="txt"><strong>Sovereign API v4</strong> — ajouter Llama 4 Scout (Groq), DeepSeek-R1 (SambaNova), Qwen3-235B-think (Cerebras). Objectif : 15/15 providers</div><div class="pri p2">P2</div></div>
</div>
<!-- FOOTER -->
<div style="text-align:center;padding:20px 0;border-top:1px solid var(--border);margin-top:20px">
<div style="font-size:.65rem;color:var(--dim)">WEVAL Consulting · Casablanca · 14 avril 2026</div>
<div style="font-size:.6rem;color:var(--dim2);margin-top:4px">Session Opus directeur de projet · 346 tools · 13 providers · 141K HCPs · 0€ IA</div>
</div>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body>
</html>

View File

@@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — Architecture Complète & Plan Scalabilité</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#09090b;--s1:#111113;--s2:#1a1a1f;--s3:#242429;
--acc:#00e5ff;--acc2:#7c3aed;--g:#22c55e;--r:#ef4444;--o:#eab308;--p:#a78bfa;
--coral:#f97066;--teal:#2dd4bf;--blue:#3b82f6;--pink:#f472b6;
--t:#f4f4f5;--dim:#a1a1aa;--dim2:#71717a;
--border:rgba(255,255,255,.06);
--hf:'JetBrains Mono',monospace;--bf:'Outfit',system-ui,sans-serif;
--radius:10px}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--bf);background:var(--bg);color:var(--t);overflow-x:hidden;line-height:1.5}
::selection{background:rgba(0,229,255,.2)}
::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:var(--dim2);border-radius:3px}
.wrap{max-width:1400px;margin:0 auto;padding:20px 24px}
/* HEADER */
.hdr{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--border);margin-bottom:24px}
.hdr h1{font-size:1.4rem;font-weight:700;letter-spacing:-.02em}
.hdr h1 span{color:var(--acc);font-family:var(--hf)}
.hdr .meta{font-size:.7rem;color:var(--dim);font-family:var(--hf)}
.hdr a{color:var(--acc);text-decoration:none;font-size:.75rem;font-family:var(--hf);border:1px solid rgba(0,229,255,.3);padding:4px 12px;border-radius:6px;transition:.2s}
.hdr a:hover{background:rgba(0,229,255,.1)}
/* KPI BAR */
.kpi-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:28px}
.kpi{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;text-align:center}
.kpi .v{font-size:1.3rem;font-weight:700;font-family:var(--hf);color:var(--acc)}
.kpi .l{font-size:.6rem;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
/* SECTIONS */
.sec{margin-bottom:28px}
.sec-title{font-size:.85rem;font-weight:600;color:var(--t);padding:8px 0;border-bottom:1px solid var(--border);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.sec-title .tag{font-size:.55rem;font-family:var(--hf);background:rgba(0,229,255,.12);color:var(--acc);padding:2px 8px;border-radius:4px}
/* GRID */
.g{display:grid;gap:8px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
@media(max-width:900px){.g3,.g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}}
/* CARDS */
.cd{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;transition:.2s;position:relative;overflow:hidden}
.cd:hover{border-color:rgba(255,255,255,.12);transform:translateY(-1px)}
.cd .name{font-size:.75rem;font-weight:600;margin-bottom:2px}
.cd .desc{font-size:.6rem;color:var(--dim);line-height:1.4}
.cd .badge{position:absolute;top:8px;right:8px;font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;font-weight:600}
.cd .dot{width:6px;height:6px;border-radius:50%;display:inline-block;margin-right:4px}
/* Colors */
.cd.purple{border-left:3px solid var(--p)}.cd.purple .name{color:var(--p)}
.cd.coral{border-left:3px solid var(--coral)}.cd.coral .name{color:var(--coral)}
.cd.teal{border-left:3px solid var(--teal)}.cd.teal .name{color:var(--teal)}
.cd.blue{border-left:3px solid var(--blue)}.cd.blue .name{color:var(--blue)}
.cd.green{border-left:3px solid var(--g)}.cd.green .name{color:var(--g)}
.cd.amber{border-left:3px solid var(--o)}.cd.amber .name{color:var(--o)}
.cd.pink{border-left:3px solid var(--pink)}.cd.pink .name{color:var(--pink)}
.cd.red{border-left:3px solid var(--r)}.cd.red .name{color:var(--r)}
.cd.gray{border-left:3px solid var(--dim2)}
.up{background:rgba(34,197,94,.15);color:var(--g)}
.down{background:rgba(239,68,68,.15);color:var(--r)}
.warn{background:rgba(234,179,8,.15);color:var(--o)}
/* PIPELINE */
.pipeline{display:flex;align-items:center;gap:0;overflow-x:auto;padding:4px 0}
.pipeline .step{background:var(--s2);border:1px solid var(--border);padding:8px 14px;font-size:.65rem;font-weight:500;white-space:nowrap;position:relative}
.pipeline .step:first-child{border-radius:var(--radius) 0 0 var(--radius)}
.pipeline .step:last-child{border-radius:0 var(--radius) var(--radius) 0}
.pipeline .arrow{color:var(--dim2);font-size:.7rem;margin:0 -1px;z-index:1}
/* PLAN */
.plan-item{display:flex;gap:10px;padding:8px 12px;background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:6px;align-items:flex-start}
.plan-item .num{font-family:var(--hf);font-size:.7rem;font-weight:700;color:var(--acc);min-width:20px}
.plan-item .txt{font-size:.68rem;color:var(--dim);line-height:1.5}
.plan-item .txt strong{color:var(--t);font-weight:600}
.plan-item .pri{font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;margin-left:auto;white-space:nowrap}
.pri.p0{background:rgba(239,68,68,.15);color:var(--r)}
.pri.p1{background:rgba(234,179,8,.15);color:var(--o)}
.pri.p2{background:rgba(59,130,246,.15);color:var(--blue)}
/* ANIM */
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sec{animation:fadeIn .4s ease both}
.sec:nth-child(2){animation-delay:.05s}
.sec:nth-child(3){animation-delay:.1s}
.sec:nth-child(4){animation-delay:.15s}
.sec:nth-child(5){animation-delay:.2s}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr">
<h1><span>WEVAL</span> Architecture Map</h1>
<div style="text-align:right">
<div class="meta">14 avril 2026 · Session Opus</div>
<a href="/architecture.html">Control Center</a>
</div>
</div>
<!-- KPIs -->
<div class="kpi-bar">
<div class="kpi"><div class="v">346</div><div class="l">Tools</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">13</div><div class="l">Providers IA</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">141K</div><div class="l">HCPs Ethica</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">150+</div><div class="l">Écrans Arsenal</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">0€</div><div class="l">Coût IA</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">3.5M</div><div class="l">Pipeline MAD</div></div>
<div class="kpi"><div class="v" style="color:var(--pink)">870</div><div class="l">Agents</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">150/152</div><div class="l">NonReg</div></div>
</div>
<!-- ═══ SECTION 1: APPS FRONTEND ═══ -->
<div class="sec">
<div class="sec-title">Applications frontend <span class="tag">22 apps</span></div>
<div class="g4">
<div class="cd purple"><div class="name">wevia.html</div><div class="desc">Chatbot IA public · Cloudflare-AI · SSE streaming</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-master.html</div><div class="desc">Master AI · 346 tools · FastPath · Resolver v8</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-cortex.html</div><div class="desc">Cortex v2.1 · Multi-agent · 669 agents</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-arena.html</div><div class="desc">Arena multi-LLM · A/B test providers</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">growth-engine-v2.html</div><div class="desc">GE v3 · 8 verticaux · Pipeline 3.5M MAD</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">blade-ai.html</div><div class="desc">Blade IA GODMODE 10/10 · 421L 30KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">office-workflow.php</div><div class="desc">CRM + process automation · 65KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">architecture.html</div><div class="desc">Control Center · scan LIVE infra</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">Ethica Dashboard</div><div class="desc">6 modules · HCP manager · consent · SMS · drill</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">l99-saas.html</div><div class="desc">L99 SaaS · 1113 files indexed</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">agents-archi.html</div><div class="desc">3D agents visualization · 94KB</div><div class="badge warn">301</div></div>
<div class="cd green"><div class="name">director-center.html</div><div class="desc">Director + Monitoring Kuma</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEDROID</div><div class="desc">Factory IA · callCloud cascade</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">OpenClaw</div><div class="desc">Code agent · terminal web</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEVCODE</div><div class="desc">IDE souverain · Monaco editor</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">Nuclei</div><div class="desc">Security scanner · vuln detection</div><div class="badge warn">IDLE</div></div>
<div class="cd blue"><div class="name">WEVADS IA (ADX)</div><div class="desc">Email pipeline · 6.6M contacts · Brain Engine</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">WEVIA Life</div><div class="desc">Session sync · chat history · wevialife-sync.php</div><div class="badge up">CRON</div></div>
<div class="cd blue"><div class="name">consent.wevup.app</div><div class="desc">RGPD landing · optin/optout tokens</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">Paperclip</div><div class="desc">870 agents · 6 projets actifs · 2484 skills</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">enterprise-model.html</div><div class="desc">669 agents · 22 depts · 3D rooms</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 2: CASCADE IA SOUVERAINE ═══ -->
<div class="sec">
<div class="sec-title">Cascade IA souveraine <span class="tag">13 providers · 0€</span></div>
<div style="background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;margin-bottom:10px">
<div style="font-size:.7rem;font-family:var(--hf);color:var(--acc);margin-bottom:8px">sovereign-api.py :4000 — auto-cascade · primary: Cerebras-fast</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 1 — Ultra-rapide (&lt;0.5s)</div>
<div class="g4" style="margin-bottom:8px">
<div class="cd coral"><div class="name">Cerebras-fast</div><div class="desc">llama-3.3-70b · 0.25s · PRIMARY</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cerebras-think</div><div class="desc">Qwen3-235B · Chain-of-Thought</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Groq</div><div class="desc">llama-3.1-8b-instant · 0.23s</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cloudflare AI</div><div class="desc">Workers AI · 10K req/j free GPU</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 2 — Rapide (&lt;2s)</div>
<div class="g5" style="margin-bottom:8px">
<div class="cd amber"><div class="name">Gemini</div><div class="desc">2.0-flash free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">SambaNova</div><div class="desc">DeepSeek-V3.2</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">NVIDIA NIM</div><div class="desc">Llama 3.1 free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">Mistral</div><div class="desc">open-nemo free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">GitHub Models</div><div class="desc">API free tier</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 3 — Fallback</div>
<div class="g4">
<div class="cd gray"><div class="name">HF Space</div><div class="desc">weval-brain-v4 fine-tuné</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">HF Router</div><div class="desc">Qwen2.5-72B serverless</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">OpenRouter</div><div class="desc">Free tier multi-model</div><div class="badge up">UP</div></div>
<div class="cd red"><div class="name">Ollama (LOCAL)</div><div class="desc">DISABLED · RAM killer · 6 modèles</div><div class="badge down">OFF</div></div>
</div>
</div>
</div>
<!-- ═══ SECTION 3: GPU FREE COMPUTE ═══ -->
<div class="sec">
<div class="sec-title">GPU free compute <span class="tag">fine-tune + inference</span></div>
<div class="g3">
<div class="cd blue"><div class="name">Kaggle T4/P100</div><div class="desc">30h/sem GPU gratuit · fine-tune LoRA · notebooks configurés</div><div class="badge up">READY</div></div>
<div class="cd blue"><div class="name">HF Space vLLM</div><div class="desc">yace222/weval-vllm · cpu-basic (GPU=PRO) · commit 5b4b422</div><div class="badge warn">CPU</div></div>
<div class="cd blue"><div class="name">Google Colab</div><div class="desc">T4 free 12h/session · notebooks prêts</div><div class="badge up">READY</div></div>
<div class="cd teal"><div class="name">CF Workers AI</div><div class="desc">10K req/jour · GPU edge Cloudflare · Llama 3.1</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">HF fine-tune</div><div class="desc">yace222/weval-brain-v4 · LoRA adapter · Qwen2.5</div><div class="badge up">TRAINED</div></div>
<div class="cd teal"><div class="name">Render / Railway</div><div class="desc">Free tier configuré · backup deploy</div><div class="badge warn">STANDBY</div></div>
</div>
</div>
<!-- ═══ SECTION 4: ETHICA B2B ═══ -->
<div class="sec">
<div class="sec-title">Ethica B2B Pharma <span class="tag">141K HCPs</span></div>
<div class="kpi-bar" style="grid-template-columns:repeat(6,1fr);margin-bottom:12px">
<div class="kpi"><div class="v" style="color:var(--g)">131,214</div><div class="l">HCPs total</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">109,692</div><div class="l">Emails</div></div>
<div class="kpi"><div class="v" style="color:var(--blue)">121,940</div><div class="l">Téléphones</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">34</div><div class="l">Spécialités</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">DZ 88K</div><div class="l">Algérie</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">MA+TN 36K</div><div class="l">Maroc + Tunisie</div></div>
</div>
<div class="pipeline" style="margin-bottom:10px">
<div class="step" style="border-left:3px solid var(--g)">Scrapers (CNAM+DabaDoc+Rich)</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--teal)">Validator DNS/MX</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--blue)">MA Boost 4x/j</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--o)">Consent wevup.app</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--coral)">Campagnes O365+PMTA</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--p)">Tracking open.php</div>
</div>
<div class="g3">
<div class="cd green"><div class="name">10 senders O365</div><div class="desc">3 tenants Graph API · 97% inbox</div></div>
<div class="cd green"><div class="name">10 SMS providers</div><div class="desc">130K SMS/jour capacité</div></div>
<div class="cd green"><div class="name">WhatsApp Meta WA</div><div class="desc">Business API configuré</div></div>
</div>
</div>
<!-- ═══ SECTION 5: INFRA SERVEURS ═══ -->
<div class="sec">
<div class="sec-title">Infrastructure serveurs <span class="tag">2 serveurs + 4 ECS</span></div>
<div class="g2" style="margin-bottom:8px">
<div class="cd blue" style="padding:14px">
<div class="name" style="font-size:.85rem">S204 — 204.168.152.13</div>
<div class="desc" style="margin-bottom:6px">10.1.0.2 · MTA + WEVIA + Ethica · RAM 32GB · Disk 67%</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> nginx :443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Apache :8443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PHP 8.4 FPM</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Docker (10)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sovereign :4000</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--r)">●</span> Ollama OFF</div>
</div>
</div>
<div class="cd teal" style="padding:14px">
<div class="name" style="font-size:.85rem">S95 — 95.216.167.89</div>
<div class="desc" style="margin-bottom:6px">10.1.0.3 · Hetzner · WEVADS prod · Arsenal · Sentinel</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PG :5432 (6.6M)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sentinel :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Arsenal :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PMTA :25</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> KumoMTA :587</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> ADX :5821</div>
</div>
</div>
</div>
<div class="cd amber" style="padding:10px">
<div class="name" style="font-size:.8rem">4 ECS Huawei — PMTA 4.5r8</div>
<div class="g4" style="margin-top:6px;gap:4px">
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_6</span><br><span style="color:var(--dim)">110.239.84.121</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_7</span><br><span style="color:var(--dim)">110.239.65.64</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_8</span><br><span style="color:var(--dim)">182.160.55.107</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_9</span><br><span style="color:var(--dim)">110.239.86.68</span></div>
</div>
</div>
</div>
<!-- ═══ SECTION 6: PIPELINE E2E ═══ -->
<div class="sec">
<div class="sec-title">Pipeline E2E email marketing <span class="tag">PULL model</span></div>
<div class="pipeline">
<div class="step" style="background:var(--s2);border-left:3px solid var(--g)">Brain Engine<br><span style="font-size:.5rem;color:var(--dim)">646 configs · 9 winners</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--blue)">Send O365/PMTA<br><span style="font-size:.5rem;color:var(--dim)">97% inbox</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--teal)">Open (open.php)<br><span style="font-size:.5rem;color:var(--dim)">S204 tracking</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--o)">Click<br><span style="font-size:.5rem;color:var(--dim)">552 links actifs</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--coral)">Conversion<br><span style="font-size:.5rem;color:var(--dim)">CAKE/Everflow</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--p)">PULL collector<br><span style="font-size:.5rem;color:var(--dim)">cron 30min</span></div>
</div>
</div>
<!-- ═══ SECTION 7: AGENTS + SERVICES ═══ -->
<div class="sec">
<div class="sec-title">Agents + services internes <span class="tag">Docker + systemd</span></div>
<div class="g4">
<div class="cd pink"><div class="name">Paperclip</div><div class="desc">870 agents · 2484 skills · 6 projets actifs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">Qdrant :6333</div><div class="desc">5 collections · 16K vecteurs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">SearXNG</div><div class="desc">Moteur de recherche privé</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Listmonk</div><div class="desc">Email marketing self-hosted</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Uptime Kuma</div><div class="desc">Monitoring 24/7</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Wiki (1194)</div><div class="desc">JSON knowledge base</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Vault GOLD (424)</div><div class="desc">Backup auto + checksums</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 8: CLOUDFLARE + DNS ═══ -->
<div class="sec">
<div class="sec-title">Cloudflare + DNS <span class="tag">41 comptes · 16 zones</span></div>
<div class="g4">
<div class="cd amber"><div class="name">weval-consulting.com</div><div class="desc">Site principal + API + WEVIA</div></div>
<div class="cd amber"><div class="name">wevup.app</div><div class="desc">consent.wevup.app + DNS Hetzner</div></div>
<div class="cd amber"><div class="name">culturellemejean.charity</div><div class="desc">Tracking domain · open.php</div></div>
<div class="cd amber"><div class="name">41 comptes CF Brahim</div><div class="desc">Rotation + multi-zone</div></div>
</div>
</div>
<!-- ═══ SECTION 9: PARTENARIATS ═══ -->
<div class="sec">
<div class="sec-title">Partenariats actifs <span class="tag">4 deals</span></div>
<div class="g4">
<div class="cd purple"><div class="name">Vistex (SAP)</div><div class="desc">Maghreb retail/pharma · litige lead protection Section 6.c.i</div></div>
<div class="cd purple"><div class="name">Scaleway / Arrow</div><div class="desc">ArrowSphere onboarding · cloud MSP</div></div>
<div class="cd purple"><div class="name">Huawei Cloud</div><div class="desc">4 ECS PMTA · litige billing actif</div></div>
<div class="cd purple"><div class="name">Ethica (Kaouther)</div><div class="desc">HCP Maghreb 2027 · email prêt</div></div>
</div>
</div>
<!-- ═══ SECTION 10: PLAN D'ACTION OPTIMISATION + SCALABILITÉ ═══ -->
<div class="sec">
<div class="sec-title">Plan d'action — optimisation + scalabilité <span class="tag">15 actions</span></div>
<div class="plan-item"><div class="num">01</div><div class="txt"><strong>HF Space GPU upgrade</strong> — passer yace222/weval-vllm de cpu-basic à GPU free (T4) quand HF PRO dispo. Objectif : inference vLLM souveraine 0€</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">02</div><div class="txt"><strong>Kaggle fine-tune pipeline</strong> — automatiser le fine-tune weval-brain-v5 sur Kaggle T4 avec les données wiki+KB (1194 entries). Objectif : modèle souverain amélioré</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">03</div><div class="txt"><strong>Ethica gap 21K emails</strong> — enrichir les 21,522 HCPs sans email via scrapers CNAM v3 + SearXNG + DabaDoc deep. Objectif : 120K+ emails</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">04</div><div class="txt"><strong>Campagne consent pilot</strong> — lancer pilot 500 DZ + 500 MA après validation Kaouther. Safety lock actif. Objectif : premiers consentements réels</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">05</div><div class="txt"><strong>Ollama selective restart</strong> — réactiver Ollama avec 1 seul modèle léger (qwen3:4b, 5GB) sur schedule cron (ON 8h-20h, OFF nuit). Objectif : inference locale sans crash RAM</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">06</div><div class="txt"><strong>WEVIA Life auto-sync</strong> — wevialife-sync.php enrichi avec session context + conversation memory → Qdrant. Objectif : mémoire persistante cross-session</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">07</div><div class="txt"><strong>NonReg 152/152</strong> — investiguer les 2 tests skip. Probablement dépendance S151 décommissionné. Objectif : 100% pass</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">08</div><div class="txt"><strong>S95 disk cleanup</strong> — disk à 85%. Purger logs, Docker images, old backups. Objectif : &lt;70%</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">09</div><div class="txt"><strong>GitHub PAT renouvellement</strong> — le token expire bientôt. Renouveler manuellement via github.com/settings/tokens</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">10</div><div class="txt"><strong>Scaleway 5 POC</strong> — déployer les 5 POC cloud (ArrowSphere). Objectif : 240K MAD pipeline</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">11</div><div class="txt"><strong>Multi-region PMTA</strong> — ajouter 2 ECS Europe (Hetzner) pour améliorer inbox EU. Objectif : 99% inbox Europe</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">12</div><div class="txt"><strong>Whisper.cpp local</strong> — réactiver voice-to-text souverain sur S204 CPU. Objectif : transcription audio WEVIA</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">13</div><div class="txt"><strong>DeerFlow réactivation</strong> — restart quand RAM stabilisée. Objectif : workflow automation</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">14</div><div class="txt"><strong>S204 RAM upgrade</strong> — passer de 16GB à 32GB pour supporter Ollama + Docker + FPM sans crash. Objectif : stabilité définitive</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">15</div><div class="txt"><strong>Sovereign API v4</strong> — ajouter Llama 4 Scout (Groq), DeepSeek-R1 (SambaNova), Qwen3-235B-think (Cerebras). Objectif : 15/15 providers</div><div class="pri p2">P2</div></div>
</div>
<!-- FOOTER -->
<div style="text-align:center;padding:20px 0;border-top:1px solid var(--border);margin-top:20px">
<div style="font-size:.65rem;color:var(--dim)">WEVAL Consulting · Casablanca · 14 avril 2026</div>
<div style="font-size:.6rem;color:var(--dim2);margin-top:4px">Session Opus directeur de projet · 346 tools · 13 providers · 141K HCPs · 0€ IA</div>
</div>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body>
</html>

View File

@@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — Architecture Complète & Plan Scalabilité</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#09090b;--s1:#111113;--s2:#1a1a1f;--s3:#242429;
--acc:#00e5ff;--acc2:#7c3aed;--g:#22c55e;--r:#ef4444;--o:#eab308;--p:#a78bfa;
--coral:#f97066;--teal:#2dd4bf;--blue:#3b82f6;--pink:#f472b6;
--t:#f4f4f5;--dim:#a1a1aa;--dim2:#71717a;
--border:rgba(255,255,255,.06);
--hf:'JetBrains Mono',monospace;--bf:'Outfit',system-ui,sans-serif;
--radius:10px}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--bf);background:var(--bg);color:var(--t);overflow-x:hidden;line-height:1.5}
::selection{background:rgba(0,229,255,.2)}
::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:var(--dim2);border-radius:3px}
.wrap{max-width:1400px;margin:0 auto;padding:20px 24px}
/* HEADER */
.hdr{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--border);margin-bottom:24px}
.hdr h1{font-size:1.4rem;font-weight:700;letter-spacing:-.02em}
.hdr h1 span{color:var(--acc);font-family:var(--hf)}
.hdr .meta{font-size:.7rem;color:var(--dim);font-family:var(--hf)}
.hdr a{color:var(--acc);text-decoration:none;font-size:.75rem;font-family:var(--hf);border:1px solid rgba(0,229,255,.3);padding:4px 12px;border-radius:6px;transition:.2s}
.hdr a:hover{background:rgba(0,229,255,.1)}
/* KPI BAR */
.kpi-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:28px}
.kpi{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;text-align:center}
.kpi .v{font-size:1.3rem;font-weight:700;font-family:var(--hf);color:var(--acc)}
.kpi .l{font-size:.6rem;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
/* SECTIONS */
.sec{margin-bottom:28px}
.sec-title{font-size:.85rem;font-weight:600;color:var(--t);padding:8px 0;border-bottom:1px solid var(--border);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.sec-title .tag{font-size:.55rem;font-family:var(--hf);background:rgba(0,229,255,.12);color:var(--acc);padding:2px 8px;border-radius:4px}
/* GRID */
.g{display:grid;gap:8px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
@media(max-width:900px){.g3,.g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}}
/* CARDS */
.cd{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;transition:.2s;position:relative;overflow:hidden}
.cd:hover{border-color:rgba(255,255,255,.12);transform:translateY(-1px)}
.cd .name{font-size:.75rem;font-weight:600;margin-bottom:2px}
.cd .desc{font-size:.6rem;color:var(--dim);line-height:1.4}
.cd .badge{position:absolute;top:8px;right:8px;font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;font-weight:600}
.cd .dot{width:6px;height:6px;border-radius:50%;display:inline-block;margin-right:4px}
/* Colors */
.cd.purple{border-left:3px solid var(--p)}.cd.purple .name{color:var(--p)}
.cd.coral{border-left:3px solid var(--coral)}.cd.coral .name{color:var(--coral)}
.cd.teal{border-left:3px solid var(--teal)}.cd.teal .name{color:var(--teal)}
.cd.blue{border-left:3px solid var(--blue)}.cd.blue .name{color:var(--blue)}
.cd.green{border-left:3px solid var(--g)}.cd.green .name{color:var(--g)}
.cd.amber{border-left:3px solid var(--o)}.cd.amber .name{color:var(--o)}
.cd.pink{border-left:3px solid var(--pink)}.cd.pink .name{color:var(--pink)}
.cd.red{border-left:3px solid var(--r)}.cd.red .name{color:var(--r)}
.cd.gray{border-left:3px solid var(--dim2)}
.up{background:rgba(34,197,94,.15);color:var(--g)}
.down{background:rgba(239,68,68,.15);color:var(--r)}
.warn{background:rgba(234,179,8,.15);color:var(--o)}
/* PIPELINE */
.pipeline{display:flex;align-items:center;gap:0;overflow-x:auto;padding:4px 0}
.pipeline .step{background:var(--s2);border:1px solid var(--border);padding:8px 14px;font-size:.65rem;font-weight:500;white-space:nowrap;position:relative}
.pipeline .step:first-child{border-radius:var(--radius) 0 0 var(--radius)}
.pipeline .step:last-child{border-radius:0 var(--radius) var(--radius) 0}
.pipeline .arrow{color:var(--dim2);font-size:.7rem;margin:0 -1px;z-index:1}
/* PLAN */
.plan-item{display:flex;gap:10px;padding:8px 12px;background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:6px;align-items:flex-start}
.plan-item .num{font-family:var(--hf);font-size:.7rem;font-weight:700;color:var(--acc);min-width:20px}
.plan-item .txt{font-size:.68rem;color:var(--dim);line-height:1.5}
.plan-item .txt strong{color:var(--t);font-weight:600}
.plan-item .pri{font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;margin-left:auto;white-space:nowrap}
.pri.p0{background:rgba(239,68,68,.15);color:var(--r)}
.pri.p1{background:rgba(234,179,8,.15);color:var(--o)}
.pri.p2{background:rgba(59,130,246,.15);color:var(--blue)}
/* ANIM */
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sec{animation:fadeIn .4s ease both}
.sec:nth-child(2){animation-delay:.05s}
.sec:nth-child(3){animation-delay:.1s}
.sec:nth-child(4){animation-delay:.15s}
.sec:nth-child(5){animation-delay:.2s}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr">
<h1><span>WEVAL</span> Architecture Map</h1>
<div style="text-align:right">
<div class="meta">14 avril 2026 · Session Opus</div>
<a href="/architecture.html">Control Center</a>
</div>
</div>
<!-- KPIs -->
<div class="kpi-bar">
<div class="kpi"><div class="v">346</div><div class="l">Tools</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">13</div><div class="l">Providers IA</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">141K</div><div class="l">HCPs Ethica</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">150+</div><div class="l">Écrans Arsenal</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">0€</div><div class="l">Coût IA</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">3.5M</div><div class="l">Pipeline MAD</div></div>
<div class="kpi"><div class="v" style="color:var(--pink)">870</div><div class="l">Agents</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">150/152</div><div class="l">NonReg</div></div>
</div>
<!-- ═══ SECTION 1: APPS FRONTEND ═══ -->
<div class="sec">
<div class="sec-title">Applications frontend <span class="tag">22 apps</span></div>
<div class="g4">
<div class="cd purple"><div class="name">wevia.html</div><div class="desc">Chatbot IA public · Cloudflare-AI · SSE streaming</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-master.html</div><div class="desc">Master AI · 346 tools · FastPath · Resolver v8</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-cortex.html</div><div class="desc">Cortex v2.1 · Multi-agent · 669 agents</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-arena.html</div><div class="desc">Arena multi-LLM · A/B test providers</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">growth-engine-v2.html</div><div class="desc">GE v3 · 8 verticaux · Pipeline 3.5M MAD</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">blade-ai.html</div><div class="desc">Blade IA GODMODE 10/10 · 421L 30KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">office-workflow.php</div><div class="desc">CRM + process automation · 65KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">architecture.html</div><div class="desc">Control Center · scan LIVE infra</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">Ethica Dashboard</div><div class="desc">6 modules · HCP manager · consent · SMS · drill</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">l99-saas.html</div><div class="desc">L99 SaaS · 1113 files indexed</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">agents-archi.html</div><div class="desc">3D agents visualization · 94KB</div><div class="badge warn">301</div></div>
<div class="cd green"><div class="name">director-center.html</div><div class="desc">Director + Monitoring Kuma</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEDROID</div><div class="desc">Factory IA · callCloud cascade</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">OpenClaw</div><div class="desc">Code agent · terminal web</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEVCODE</div><div class="desc">IDE souverain · Monaco editor</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">Nuclei</div><div class="desc">Security scanner · vuln detection</div><div class="badge warn">IDLE</div></div>
<div class="cd blue"><div class="name">WEVADS IA (ADX)</div><div class="desc">Email pipeline · 6.6M contacts · Brain Engine</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">WEVIA Life</div><div class="desc">Session sync · chat history · wevialife-sync.php</div><div class="badge up">CRON</div></div>
<div class="cd blue"><div class="name">consent.wevup.app</div><div class="desc">RGPD landing · optin/optout tokens</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">Paperclip</div><div class="desc">870 agents · 6 projets actifs · 2484 skills</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">enterprise-model.html</div><div class="desc">669 agents · 22 depts · 3D rooms</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 2: CASCADE IA SOUVERAINE ═══ -->
<div class="sec">
<div class="sec-title">Cascade IA souveraine <span class="tag">13 providers · 0€</span></div>
<div style="background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;margin-bottom:10px">
<div style="font-size:.7rem;font-family:var(--hf);color:var(--acc);margin-bottom:8px">sovereign-api.py :4000 — auto-cascade · primary: Cerebras-fast</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 1 — Ultra-rapide (&lt;0.5s)</div>
<div class="g4" style="margin-bottom:8px">
<div class="cd coral"><div class="name">Cerebras-fast</div><div class="desc">llama-3.3-70b · 0.25s · PRIMARY</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cerebras-think</div><div class="desc">Qwen3-235B · Chain-of-Thought</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Groq</div><div class="desc">llama-3.1-8b-instant · 0.23s</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cloudflare AI</div><div class="desc">Workers AI · 10K req/j free GPU</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 2 — Rapide (&lt;2s)</div>
<div class="g5" style="margin-bottom:8px">
<div class="cd amber"><div class="name">Gemini</div><div class="desc">2.0-flash free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">SambaNova</div><div class="desc">DeepSeek-V3.2</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">NVIDIA NIM</div><div class="desc">Llama 3.1 free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">Mistral</div><div class="desc">open-nemo free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">GitHub Models</div><div class="desc">API free tier</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 3 — Fallback</div>
<div class="g4">
<div class="cd gray"><div class="name">HF Space</div><div class="desc">weval-brain-v4 fine-tuné</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">HF Router</div><div class="desc">Qwen2.5-72B serverless</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">OpenRouter</div><div class="desc">Free tier multi-model</div><div class="badge up">UP</div></div>
<div class="cd red"><div class="name">Ollama (LOCAL)</div><div class="desc">DISABLED · RAM killer · 6 modèles</div><div class="badge down">OFF</div></div>
</div>
</div>
</div>
<!-- ═══ SECTION 3: GPU FREE COMPUTE ═══ -->
<div class="sec">
<div class="sec-title">GPU free compute <span class="tag">fine-tune + inference</span></div>
<div class="g3">
<div class="cd blue"><div class="name">Kaggle T4/P100</div><div class="desc">30h/sem GPU gratuit · fine-tune LoRA · notebooks configurés</div><div class="badge up">READY</div></div>
<div class="cd blue"><div class="name">HF Space vLLM</div><div class="desc">yace222/weval-vllm · cpu-basic (GPU=PRO) · commit 5b4b422</div><div class="badge warn">CPU</div></div>
<div class="cd blue"><div class="name">Google Colab</div><div class="desc">T4 free 12h/session · notebooks prêts</div><div class="badge up">READY</div></div>
<div class="cd teal"><div class="name">CF Workers AI</div><div class="desc">10K req/jour · GPU edge Cloudflare · Llama 3.1</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">HF fine-tune</div><div class="desc">yace222/weval-brain-v4 · LoRA adapter · Qwen2.5</div><div class="badge up">TRAINED</div></div>
<div class="cd teal"><div class="name">Render / Railway</div><div class="desc">Free tier configuré · backup deploy</div><div class="badge warn">STANDBY</div></div>
</div>
</div>
<!-- ═══ SECTION 4: ETHICA B2B ═══ -->
<div class="sec">
<div class="sec-title">Ethica B2B Pharma <span class="tag">141K HCPs</span></div>
<div class="kpi-bar" style="grid-template-columns:repeat(6,1fr);margin-bottom:12px">
<div class="kpi"><div class="v" style="color:var(--g)">131,214</div><div class="l">HCPs total</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">109,692</div><div class="l">Emails</div></div>
<div class="kpi"><div class="v" style="color:var(--blue)">121,940</div><div class="l">Téléphones</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">34</div><div class="l">Spécialités</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">DZ 88K</div><div class="l">Algérie</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">MA+TN 36K</div><div class="l">Maroc + Tunisie</div></div>
</div>
<div class="pipeline" style="margin-bottom:10px">
<div class="step" style="border-left:3px solid var(--g)">Scrapers (CNAM+DabaDoc+Rich)</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--teal)">Validator DNS/MX</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--blue)">MA Boost 4x/j</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--o)">Consent wevup.app</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--coral)">Campagnes O365+PMTA</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--p)">Tracking open.php</div>
</div>
<div class="g3">
<div class="cd green"><div class="name">10 senders O365</div><div class="desc">3 tenants Graph API · 97% inbox</div></div>
<div class="cd green"><div class="name">10 SMS providers</div><div class="desc">130K SMS/jour capacité</div></div>
<div class="cd green"><div class="name">WhatsApp Meta WA</div><div class="desc">Business API configuré</div></div>
</div>
</div>
<!-- ═══ SECTION 5: INFRA SERVEURS ═══ -->
<div class="sec">
<div class="sec-title">Infrastructure serveurs <span class="tag">2 serveurs + 4 ECS</span></div>
<div class="g2" style="margin-bottom:8px">
<div class="cd blue" style="padding:14px">
<div class="name" style="font-size:.85rem">S204 — 204.168.152.13</div>
<div class="desc" style="margin-bottom:6px">10.1.0.2 · MTA + WEVIA + Ethica · RAM 32GB · Disk 67%</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> nginx :443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Apache :8443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PHP 8.4 FPM</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Docker (10)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sovereign :4000</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--r)">●</span> Ollama OFF</div>
</div>
</div>
<div class="cd teal" style="padding:14px">
<div class="name" style="font-size:.85rem">S95 — 95.216.167.89</div>
<div class="desc" style="margin-bottom:6px">10.1.0.3 · Hetzner · WEVADS prod · Arsenal · Sentinel</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PG :5432 (6.6M)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sentinel :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Arsenal :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PMTA :25</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> KumoMTA :587</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> ADX :5821</div>
</div>
</div>
</div>
<div class="cd amber" style="padding:10px">
<div class="name" style="font-size:.8rem">4 ECS Huawei — PMTA 4.5r8</div>
<div class="g4" style="margin-top:6px;gap:4px">
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_6</span><br><span style="color:var(--dim)">110.239.84.121</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_7</span><br><span style="color:var(--dim)">110.239.65.64</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_8</span><br><span style="color:var(--dim)">182.160.55.107</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_9</span><br><span style="color:var(--dim)">110.239.86.68</span></div>
</div>
</div>
</div>
<!-- ═══ SECTION 6: PIPELINE E2E ═══ -->
<div class="sec">
<div class="sec-title">Pipeline E2E email marketing <span class="tag">PULL model</span></div>
<div class="pipeline">
<div class="step" style="background:var(--s2);border-left:3px solid var(--g)">Brain Engine<br><span style="font-size:.5rem;color:var(--dim)">646 configs · 9 winners</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--blue)">Send O365/PMTA<br><span style="font-size:.5rem;color:var(--dim)">97% inbox</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--teal)">Open (open.php)<br><span style="font-size:.5rem;color:var(--dim)">S204 tracking</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--o)">Click<br><span style="font-size:.5rem;color:var(--dim)">552 links actifs</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--coral)">Conversion<br><span style="font-size:.5rem;color:var(--dim)">CAKE/Everflow</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--p)">PULL collector<br><span style="font-size:.5rem;color:var(--dim)">cron 30min</span></div>
</div>
</div>
<!-- ═══ SECTION 7: AGENTS + SERVICES ═══ -->
<div class="sec">
<div class="sec-title">Agents + services internes <span class="tag">Docker + systemd</span></div>
<div class="g4">
<div class="cd pink"><div class="name">Paperclip</div><div class="desc">870 agents · 2484 skills · 6 projets actifs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">Qdrant :6333</div><div class="desc">5 collections · 16K vecteurs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">SearXNG</div><div class="desc">Moteur de recherche privé</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Listmonk</div><div class="desc">Email marketing self-hosted</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Uptime Kuma</div><div class="desc">Monitoring 24/7</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Wiki (1194)</div><div class="desc">JSON knowledge base</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Vault GOLD (424)</div><div class="desc">Backup auto + checksums</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 8: CLOUDFLARE + DNS ═══ -->
<div class="sec">
<div class="sec-title">Cloudflare + DNS <span class="tag">41 comptes · 16 zones</span></div>
<div class="g4">
<div class="cd amber"><div class="name">weval-consulting.com</div><div class="desc">Site principal + API + WEVIA</div></div>
<div class="cd amber"><div class="name">wevup.app</div><div class="desc">consent.wevup.app + DNS Hetzner</div></div>
<div class="cd amber"><div class="name">culturellemejean.charity</div><div class="desc">Tracking domain · open.php</div></div>
<div class="cd amber"><div class="name">41 comptes CF Brahim</div><div class="desc">Rotation + multi-zone</div></div>
</div>
</div>
<!-- ═══ SECTION 9: PARTENARIATS ═══ -->
<div class="sec">
<div class="sec-title">Partenariats actifs <span class="tag">4 deals</span></div>
<div class="g4">
<div class="cd purple"><div class="name">Vistex (SAP)</div><div class="desc">Maghreb retail/pharma · litige lead protection Section 6.c.i</div></div>
<div class="cd purple"><div class="name">Scaleway / Arrow</div><div class="desc">ArrowSphere onboarding · cloud MSP</div></div>
<div class="cd purple"><div class="name">Huawei Cloud</div><div class="desc">4 ECS PMTA · litige billing actif</div></div>
<div class="cd purple"><div class="name">Ethica (Kaouther)</div><div class="desc">HCP Maghreb 2027 · email prêt</div></div>
</div>
</div>
<!-- ═══ SECTION 10: PLAN D'ACTION OPTIMISATION + SCALABILITÉ ═══ -->
<div class="sec">
<div class="sec-title">Plan d'action — optimisation + scalabilité <span class="tag">15 actions</span></div>
<div class="plan-item"><div class="num">01</div><div class="txt"><strong>HF Space GPU upgrade</strong> — passer yace222/weval-vllm de cpu-basic à GPU free (T4) quand HF PRO dispo. Objectif : inference vLLM souveraine 0€</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">02</div><div class="txt"><strong>Kaggle fine-tune pipeline</strong> — automatiser le fine-tune weval-brain-v5 sur Kaggle T4 avec les données wiki+KB (1194 entries). Objectif : modèle souverain amélioré</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">03</div><div class="txt"><strong>Ethica gap 21K emails</strong> — enrichir les 21,522 HCPs sans email via scrapers CNAM v3 + SearXNG + DabaDoc deep. Objectif : 120K+ emails</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">04</div><div class="txt"><strong>Campagne consent pilot</strong> — lancer pilot 500 DZ + 500 MA après validation Kaouther. Safety lock actif. Objectif : premiers consentements réels</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">05</div><div class="txt"><strong>Ollama selective restart</strong> — réactiver Ollama avec 1 seul modèle léger (qwen3:4b, 5GB) sur schedule cron (ON 8h-20h, OFF nuit). Objectif : inference locale sans crash RAM</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">06</div><div class="txt"><strong>WEVIA Life auto-sync</strong> — wevialife-sync.php enrichi avec session context + conversation memory → Qdrant. Objectif : mémoire persistante cross-session</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">07</div><div class="txt"><strong>NonReg 152/152</strong> — investiguer les 2 tests skip. Probablement dépendance S151 décommissionné. Objectif : 100% pass</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">08</div><div class="txt"><strong>S95 disk cleanup</strong> — disk à 85%. Purger logs, Docker images, old backups. Objectif : &lt;70%</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">09</div><div class="txt"><strong>GitHub PAT renouvellement</strong> — le token expire bientôt. Renouveler manuellement via github.com/settings/tokens</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">10</div><div class="txt"><strong>Scaleway 5 POC</strong> — déployer les 5 POC cloud (ArrowSphere). Objectif : 240K MAD pipeline</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">11</div><div class="txt"><strong>Multi-region PMTA</strong> — ajouter 2 ECS Europe (Hetzner) pour améliorer inbox EU. Objectif : 99% inbox Europe</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">12</div><div class="txt"><strong>Whisper.cpp local</strong> — réactiver voice-to-text souverain sur S204 CPU. Objectif : transcription audio WEVIA</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">13</div><div class="txt"><strong>DeerFlow réactivation</strong> — restart quand RAM stabilisée. Objectif : workflow automation</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">14</div><div class="txt"><strong>S204 RAM upgrade</strong> — passer de 16GB à 32GB pour supporter Ollama + Docker + FPM sans crash. Objectif : stabilité définitive</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">15</div><div class="txt"><strong>Sovereign API v4</strong> — ajouter Llama 4 Scout (Groq), DeepSeek-R1 (SambaNova), Qwen3-235B-think (Cerebras). Objectif : 15/15 providers</div><div class="pri p2">P2</div></div>
</div>
<!-- FOOTER -->
<div style="text-align:center;padding:20px 0;border-top:1px solid var(--border);margin-top:20px">
<div style="font-size:.65rem;color:var(--dim)">WEVAL Consulting · Casablanca · 14 avril 2026</div>
<div style="font-size:.6rem;color:var(--dim2);margin-top:4px">Session Opus directeur de projet · 346 tools · 13 providers · 141K HCPs · 0€ IA</div>
</div>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body>
</html>

View File

@@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — Architecture Complète & Plan Scalabilité</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#09090b;--s1:#111113;--s2:#1a1a1f;--s3:#242429;
--acc:#00e5ff;--acc2:#7c3aed;--g:#22c55e;--r:#ef4444;--o:#eab308;--p:#a78bfa;
--coral:#f97066;--teal:#2dd4bf;--blue:#3b82f6;--pink:#f472b6;
--t:#f4f4f5;--dim:#a1a1aa;--dim2:#71717a;
--border:rgba(255,255,255,.06);
--hf:'JetBrains Mono',monospace;--bf:'Outfit',system-ui,sans-serif;
--radius:10px}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--bf);background:var(--bg);color:var(--t);overflow-x:hidden;line-height:1.5}
::selection{background:rgba(0,229,255,.2)}
::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:var(--dim2);border-radius:3px}
.wrap{max-width:1400px;margin:0 auto;padding:20px 24px}
/* HEADER */
.hdr{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--border);margin-bottom:24px}
.hdr h1{font-size:1.4rem;font-weight:700;letter-spacing:-.02em}
.hdr h1 span{color:var(--acc);font-family:var(--hf)}
.hdr .meta{font-size:.7rem;color:var(--dim);font-family:var(--hf)}
.hdr a{color:var(--acc);text-decoration:none;font-size:.75rem;font-family:var(--hf);border:1px solid rgba(0,229,255,.3);padding:4px 12px;border-radius:6px;transition:.2s}
.hdr a:hover{background:rgba(0,229,255,.1)}
/* KPI BAR */
.kpi-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:28px}
.kpi{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;text-align:center}
.kpi .v{font-size:1.3rem;font-weight:700;font-family:var(--hf);color:var(--acc)}
.kpi .l{font-size:.6rem;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
/* SECTIONS */
.sec{margin-bottom:28px}
.sec-title{font-size:.85rem;font-weight:600;color:var(--t);padding:8px 0;border-bottom:1px solid var(--border);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.sec-title .tag{font-size:.55rem;font-family:var(--hf);background:rgba(0,229,255,.12);color:var(--acc);padding:2px 8px;border-radius:4px}
/* GRID */
.g{display:grid;gap:8px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
.g6{grid-template-columns:repeat(6,1fr)}
@media(max-width:900px){.g3,.g4,.g5,.g6{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}}
/* CARDS */
.cd{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;transition:.2s;position:relative;overflow:hidden}
.cd:hover{border-color:rgba(255,255,255,.12);transform:translateY(-1px)}
.cd .name{font-size:.75rem;font-weight:600;margin-bottom:2px}
.cd .desc{font-size:.6rem;color:var(--dim);line-height:1.4}
.cd .badge{position:absolute;top:8px;right:8px;font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;font-weight:600}
.cd .dot{width:6px;height:6px;border-radius:50%;display:inline-block;margin-right:4px}
/* Colors */
.cd.purple{border-left:3px solid var(--p)}.cd.purple .name{color:var(--p)}
.cd.coral{border-left:3px solid var(--coral)}.cd.coral .name{color:var(--coral)}
.cd.teal{border-left:3px solid var(--teal)}.cd.teal .name{color:var(--teal)}
.cd.blue{border-left:3px solid var(--blue)}.cd.blue .name{color:var(--blue)}
.cd.green{border-left:3px solid var(--g)}.cd.green .name{color:var(--g)}
.cd.amber{border-left:3px solid var(--o)}.cd.amber .name{color:var(--o)}
.cd.pink{border-left:3px solid var(--pink)}.cd.pink .name{color:var(--pink)}
.cd.red{border-left:3px solid var(--r)}.cd.red .name{color:var(--r)}
.cd.gray{border-left:3px solid var(--dim2)}
.up{background:rgba(34,197,94,.15);color:var(--g)}
.down{background:rgba(239,68,68,.15);color:var(--r)}
.warn{background:rgba(234,179,8,.15);color:var(--o)}
/* PIPELINE */
.pipeline{display:flex;align-items:center;gap:0;overflow-x:auto;padding:4px 0}
.pipeline .step{background:var(--s2);border:1px solid var(--border);padding:8px 14px;font-size:.65rem;font-weight:500;white-space:nowrap;position:relative}
.pipeline .step:first-child{border-radius:var(--radius) 0 0 var(--radius)}
.pipeline .step:last-child{border-radius:0 var(--radius) var(--radius) 0}
.pipeline .arrow{color:var(--dim2);font-size:.7rem;margin:0 -1px;z-index:1}
/* PLAN */
.plan-item{display:flex;gap:10px;padding:8px 12px;background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:6px;align-items:flex-start}
.plan-item .num{font-family:var(--hf);font-size:.7rem;font-weight:700;color:var(--acc);min-width:20px}
.plan-item .txt{font-size:.68rem;color:var(--dim);line-height:1.5}
.plan-item .txt strong{color:var(--t);font-weight:600}
.plan-item .pri{font-size:.5rem;font-family:var(--hf);padding:2px 6px;border-radius:3px;margin-left:auto;white-space:nowrap}
.pri.p0{background:rgba(239,68,68,.15);color:var(--r)}
.pri.p1{background:rgba(234,179,8,.15);color:var(--o)}
.pri.p2{background:rgba(59,130,246,.15);color:var(--blue)}
/* ANIM */
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.sec{animation:fadeIn .4s ease both}
.sec:nth-child(2){animation-delay:.05s}
.sec:nth-child(3){animation-delay:.1s}
.sec:nth-child(4){animation-delay:.15s}
.sec:nth-child(5){animation-delay:.2s}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr">
<h1><span>WEVAL</span> Architecture Map</h1>
<div style="text-align:right">
<div class="meta">14 avril 2026 · Session Opus</div>
<a href="/architecture.html">Control Center</a>
</div>
</div>
<!-- KPIs -->
<div class="kpi-bar">
<div class="kpi"><div class="v">346</div><div class="l">Tools</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">13</div><div class="l">Providers IA</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">141K</div><div class="l">HCPs Ethica</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">150+</div><div class="l">Écrans Arsenal</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">0€</div><div class="l">Coût IA</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">3.5M</div><div class="l">Pipeline MAD</div></div>
<div class="kpi"><div class="v" style="color:var(--pink)">870</div><div class="l">Agents</div></div>
<div class="kpi"><div class="v" style="color:var(--g)">150/152</div><div class="l">NonReg</div></div>
</div>
<!-- ═══ SECTION 1: APPS FRONTEND ═══ -->
<div class="sec">
<div class="sec-title">Applications frontend <span class="tag">22 apps</span></div>
<div class="g4">
<div class="cd purple"><div class="name">wevia.html</div><div class="desc">Chatbot IA public · Cloudflare-AI · SSE streaming</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-master.html</div><div class="desc">Master AI · 346 tools · FastPath · Resolver v8</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-cortex.html</div><div class="desc">Cortex v2.1 · Multi-agent · 669 agents</div><div class="badge up">LIVE</div></div>
<div class="cd purple"><div class="name">wevia-arena.html</div><div class="desc">Arena multi-LLM · A/B test providers</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">growth-engine-v2.html</div><div class="desc">GE v3 · 8 verticaux · Pipeline 3.5M MAD</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">blade-ai.html</div><div class="desc">Blade IA GODMODE 10/10 · 421L 30KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">office-workflow.php</div><div class="desc">CRM + process automation · 65KB</div><div class="badge up">LIVE</div></div>
<div class="cd coral"><div class="name">architecture.html</div><div class="desc">Control Center · scan LIVE infra</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">Ethica Dashboard</div><div class="desc">6 modules · HCP manager · consent · SMS · drill</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">l99-saas.html</div><div class="desc">L99 SaaS · 1113 files indexed</div><div class="badge up">LIVE</div></div>
<div class="cd green"><div class="name">agents-archi.html</div><div class="desc">3D agents visualization · 94KB</div><div class="badge warn">301</div></div>
<div class="cd green"><div class="name">director-center.html</div><div class="desc">Director + Monitoring Kuma</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEDROID</div><div class="desc">Factory IA · callCloud cascade</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">OpenClaw</div><div class="desc">Code agent · terminal web</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">WEVCODE</div><div class="desc">IDE souverain · Monaco editor</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">Nuclei</div><div class="desc">Security scanner · vuln detection</div><div class="badge warn">IDLE</div></div>
<div class="cd blue"><div class="name">WEVADS IA (ADX)</div><div class="desc">Email pipeline · 6.6M contacts · Brain Engine</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">WEVIA Life</div><div class="desc">Session sync · chat history · wevialife-sync.php</div><div class="badge up">CRON</div></div>
<div class="cd blue"><div class="name">consent.wevup.app</div><div class="desc">RGPD landing · optin/optout tokens</div><div class="badge up">LIVE</div></div>
<div class="cd blue"><div class="name">Paperclip</div><div class="desc">870 agents · 6 projets actifs · 2484 skills</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">enterprise-model.html</div><div class="desc">669 agents · 22 depts · 3D rooms</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 2: CASCADE IA SOUVERAINE ═══ -->
<div class="sec">
<div class="sec-title">Cascade IA souveraine <span class="tag">13 providers · 0€</span></div>
<div style="background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:12px;margin-bottom:10px">
<div style="font-size:.7rem;font-family:var(--hf);color:var(--acc);margin-bottom:8px">sovereign-api.py :4000 — auto-cascade · primary: Cerebras-fast</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 1 — Ultra-rapide (&lt;0.5s)</div>
<div class="g4" style="margin-bottom:8px">
<div class="cd coral"><div class="name">Cerebras-fast</div><div class="desc">llama-3.3-70b · 0.25s · PRIMARY</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cerebras-think</div><div class="desc">Qwen3-235B · Chain-of-Thought</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Groq</div><div class="desc">llama-3.1-8b-instant · 0.23s</div><div class="badge up">UP</div></div>
<div class="cd coral"><div class="name">Cloudflare AI</div><div class="desc">Workers AI · 10K req/j free GPU</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 2 — Rapide (&lt;2s)</div>
<div class="g5" style="margin-bottom:8px">
<div class="cd amber"><div class="name">Gemini</div><div class="desc">2.0-flash free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">SambaNova</div><div class="desc">DeepSeek-V3.2</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">NVIDIA NIM</div><div class="desc">Llama 3.1 free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">Mistral</div><div class="desc">open-nemo free</div><div class="badge up">UP</div></div>
<div class="cd amber"><div class="name">GitHub Models</div><div class="desc">API free tier</div><div class="badge up">UP</div></div>
</div>
<div style="font-size:.6rem;color:var(--dim);margin-bottom:4px">Tier 3 — Fallback</div>
<div class="g4">
<div class="cd gray"><div class="name">HF Space</div><div class="desc">weval-brain-v4 fine-tuné</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">HF Router</div><div class="desc">Qwen2.5-72B serverless</div><div class="badge up">UP</div></div>
<div class="cd gray"><div class="name">OpenRouter</div><div class="desc">Free tier multi-model</div><div class="badge up">UP</div></div>
<div class="cd red"><div class="name">Ollama (LOCAL)</div><div class="desc">DISABLED · RAM killer · 6 modèles</div><div class="badge down">OFF</div></div>
</div>
</div>
</div>
<!-- ═══ SECTION 3: GPU FREE COMPUTE ═══ -->
<div class="sec">
<div class="sec-title">GPU free compute <span class="tag">fine-tune + inference</span></div>
<div class="g3">
<div class="cd blue"><div class="name">Kaggle T4/P100</div><div class="desc">30h/sem GPU gratuit · fine-tune LoRA · notebooks configurés</div><div class="badge up">READY</div></div>
<div class="cd blue"><div class="name">HF Space vLLM</div><div class="desc">yace222/weval-vllm · cpu-basic (GPU=PRO) · commit 5b4b422</div><div class="badge warn">CPU</div></div>
<div class="cd blue"><div class="name">Google Colab</div><div class="desc">T4 free 12h/session · notebooks prêts</div><div class="badge up">READY</div></div>
<div class="cd teal"><div class="name">CF Workers AI</div><div class="desc">10K req/jour · GPU edge Cloudflare · Llama 3.1</div><div class="badge up">LIVE</div></div>
<div class="cd teal"><div class="name">HF fine-tune</div><div class="desc">yace222/weval-brain-v4 · LoRA adapter · Qwen2.5</div><div class="badge up">TRAINED</div></div>
<div class="cd teal"><div class="name">Render / Railway</div><div class="desc">Free tier configuré · backup deploy</div><div class="badge warn">STANDBY</div></div>
</div>
</div>
<!-- ═══ SECTION 4: ETHICA B2B ═══ -->
<div class="sec">
<div class="sec-title">Ethica B2B Pharma <span class="tag">141K HCPs</span></div>
<div class="kpi-bar" style="grid-template-columns:repeat(6,1fr);margin-bottom:12px">
<div class="kpi"><div class="v" style="color:var(--g)">131,214</div><div class="l">HCPs total</div></div>
<div class="kpi"><div class="v" style="color:var(--teal)">109,692</div><div class="l">Emails</div></div>
<div class="kpi"><div class="v" style="color:var(--blue)">121,940</div><div class="l">Téléphones</div></div>
<div class="kpi"><div class="v" style="color:var(--o)">34</div><div class="l">Spécialités</div></div>
<div class="kpi"><div class="v" style="color:var(--p)">DZ 88K</div><div class="l">Algérie</div></div>
<div class="kpi"><div class="v" style="color:var(--coral)">MA+TN 36K</div><div class="l">Maroc + Tunisie</div></div>
</div>
<div class="pipeline" style="margin-bottom:10px">
<div class="step" style="border-left:3px solid var(--g)">Scrapers (CNAM+DabaDoc+Rich)</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--teal)">Validator DNS/MX</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--blue)">MA Boost 4x/j</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--o)">Consent wevup.app</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--coral)">Campagnes O365+PMTA</div><div class="arrow">→</div>
<div class="step" style="border-left:3px solid var(--p)">Tracking open.php</div>
</div>
<div class="g3">
<div class="cd green"><div class="name">10 senders O365</div><div class="desc">3 tenants Graph API · 97% inbox</div></div>
<div class="cd green"><div class="name">10 SMS providers</div><div class="desc">130K SMS/jour capacité</div></div>
<div class="cd green"><div class="name">WhatsApp Meta WA</div><div class="desc">Business API configuré</div></div>
</div>
</div>
<!-- ═══ SECTION 5: INFRA SERVEURS ═══ -->
<div class="sec">
<div class="sec-title">Infrastructure serveurs <span class="tag">2 serveurs + 4 ECS</span></div>
<div class="g2" style="margin-bottom:8px">
<div class="cd blue" style="padding:14px">
<div class="name" style="font-size:.85rem">S204 — 204.168.152.13</div>
<div class="desc" style="margin-bottom:6px">10.1.0.2 · MTA + WEVIA + Ethica · RAM 32GB · Disk 67%</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> nginx :443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Apache :8443</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PHP 8.4 FPM</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Docker (10)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sovereign :4000</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--r)">●</span> Ollama OFF</div>
</div>
</div>
<div class="cd teal" style="padding:14px">
<div class="name" style="font-size:.85rem">S95 — 95.216.167.89</div>
<div class="desc" style="margin-bottom:6px">10.1.0.3 · Hetzner · WEVADS prod · Arsenal · Sentinel</div>
<div class="g3" style="gap:4px">
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PG :5432 (6.6M)</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Sentinel :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> Arsenal :5890</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> PMTA :25</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> KumoMTA :587</div>
<div style="background:var(--s2);padding:4px 8px;border-radius:4px;font-size:.58rem;color:var(--dim)"><span style="color:var(--g)">●</span> ADX :5821</div>
</div>
</div>
</div>
<div class="cd amber" style="padding:10px">
<div class="name" style="font-size:.8rem">4 ECS Huawei — PMTA 4.5r8</div>
<div class="g4" style="margin-top:6px;gap:4px">
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_6</span><br><span style="color:var(--dim)">110.239.84.121</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_7</span><br><span style="color:var(--dim)">110.239.65.64</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_8</span><br><span style="color:var(--dim)">182.160.55.107</span></div>
<div style="background:var(--s2);padding:6px 8px;border-radius:4px;font-size:.6rem;text-align:center"><span style="color:var(--o);font-family:var(--hf)">SER_9</span><br><span style="color:var(--dim)">110.239.86.68</span></div>
</div>
</div>
</div>
<!-- ═══ SECTION 6: PIPELINE E2E ═══ -->
<div class="sec">
<div class="sec-title">Pipeline E2E email marketing <span class="tag">PULL model</span></div>
<div class="pipeline">
<div class="step" style="background:var(--s2);border-left:3px solid var(--g)">Brain Engine<br><span style="font-size:.5rem;color:var(--dim)">646 configs · 9 winners</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--blue)">Send O365/PMTA<br><span style="font-size:.5rem;color:var(--dim)">97% inbox</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--teal)">Open (open.php)<br><span style="font-size:.5rem;color:var(--dim)">S204 tracking</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--o)">Click<br><span style="font-size:.5rem;color:var(--dim)">552 links actifs</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--coral)">Conversion<br><span style="font-size:.5rem;color:var(--dim)">CAKE/Everflow</span></div><div class="arrow">→</div>
<div class="step" style="background:var(--s2);border-left:3px solid var(--p)">PULL collector<br><span style="font-size:.5rem;color:var(--dim)">cron 30min</span></div>
</div>
</div>
<!-- ═══ SECTION 7: AGENTS + SERVICES ═══ -->
<div class="sec">
<div class="sec-title">Agents + services internes <span class="tag">Docker + systemd</span></div>
<div class="g4">
<div class="cd pink"><div class="name">Paperclip</div><div class="desc">870 agents · 2484 skills · 6 projets actifs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">MiroFish :5001</div><div class="desc">Flask AI agent · CEO layer</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">Qdrant :6333</div><div class="desc">5 collections · 16K vecteurs</div><div class="badge up">LIVE</div></div>
<div class="cd pink"><div class="name">SearXNG</div><div class="desc">Moteur de recherche privé</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Listmonk</div><div class="desc">Email marketing self-hosted</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Uptime Kuma</div><div class="desc">Monitoring 24/7</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Wiki (1194)</div><div class="desc">JSON knowledge base</div><div class="badge up">LIVE</div></div>
<div class="cd gray"><div class="name">Vault GOLD (424)</div><div class="desc">Backup auto + checksums</div><div class="badge up">LIVE</div></div>
</div>
</div>
<!-- ═══ SECTION 8: CLOUDFLARE + DNS ═══ -->
<div class="sec">
<div class="sec-title">Cloudflare + DNS <span class="tag">41 comptes · 16 zones</span></div>
<div class="g4">
<div class="cd amber"><div class="name">weval-consulting.com</div><div class="desc">Site principal + API + WEVIA</div></div>
<div class="cd amber"><div class="name">wevup.app</div><div class="desc">consent.wevup.app + DNS Hetzner</div></div>
<div class="cd amber"><div class="name">culturellemejean.charity</div><div class="desc">Tracking domain · open.php</div></div>
<div class="cd amber"><div class="name">41 comptes CF Brahim</div><div class="desc">Rotation + multi-zone</div></div>
</div>
</div>
<!-- ═══ SECTION 9: PARTENARIATS ═══ -->
<div class="sec">
<div class="sec-title">Partenariats actifs <span class="tag">4 deals</span></div>
<div class="g4">
<div class="cd purple"><div class="name">Vistex (SAP)</div><div class="desc">Maghreb retail/pharma · litige lead protection Section 6.c.i</div></div>
<div class="cd purple"><div class="name">Scaleway / Arrow</div><div class="desc">ArrowSphere onboarding · cloud MSP</div></div>
<div class="cd purple"><div class="name">Huawei Cloud</div><div class="desc">4 ECS PMTA · litige billing actif</div></div>
<div class="cd purple"><div class="name">Ethica (Kaouther)</div><div class="desc">HCP Maghreb 2027 · email prêt</div></div>
</div>
</div>
<!-- ═══ SECTION 10: PLAN D'ACTION OPTIMISATION + SCALABILITÉ ═══ -->
<div class="sec">
<div class="sec-title">Plan d'action — optimisation + scalabilité <span class="tag">15 actions</span></div>
<div class="plan-item"><div class="num">01</div><div class="txt"><strong>HF Space GPU upgrade</strong> — passer yace222/weval-vllm de cpu-basic à GPU free (T4) quand HF PRO dispo. Objectif : inference vLLM souveraine 0€</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">02</div><div class="txt"><strong>Kaggle fine-tune pipeline</strong> — automatiser le fine-tune weval-brain-v5 sur Kaggle T4 avec les données wiki+KB (1194 entries). Objectif : modèle souverain amélioré</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">03</div><div class="txt"><strong>Ethica gap 21K emails</strong> — enrichir les 21,522 HCPs sans email via scrapers CNAM v3 + SearXNG + DabaDoc deep. Objectif : 120K+ emails</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">04</div><div class="txt"><strong>Campagne consent pilot</strong> — lancer pilot 500 DZ + 500 MA après validation Kaouther. Safety lock actif. Objectif : premiers consentements réels</div><div class="pri p0">P0</div></div>
<div class="plan-item"><div class="num">05</div><div class="txt"><strong>Ollama selective restart</strong> — réactiver Ollama avec 1 seul modèle léger (qwen3:4b, 5GB) sur schedule cron (ON 8h-20h, OFF nuit). Objectif : inference locale sans crash RAM</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">06</div><div class="txt"><strong>WEVIA Life auto-sync</strong> — wevialife-sync.php enrichi avec session context + conversation memory → Qdrant. Objectif : mémoire persistante cross-session</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">07</div><div class="txt"><strong>NonReg 152/152</strong> — investiguer les 2 tests skip. Probablement dépendance S151 décommissionné. Objectif : 100% pass</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">08</div><div class="txt"><strong>S95 disk cleanup</strong> — disk à 85%. Purger logs, Docker images, old backups. Objectif : &lt;70%</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">09</div><div class="txt"><strong>GitHub PAT renouvellement</strong> — le token expire bientôt. Renouveler manuellement via github.com/settings/tokens</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">10</div><div class="txt"><strong>Scaleway 5 POC</strong> — déployer les 5 POC cloud (ArrowSphere). Objectif : 240K MAD pipeline</div><div class="pri p1">P1</div></div>
<div class="plan-item"><div class="num">11</div><div class="txt"><strong>Multi-region PMTA</strong> — ajouter 2 ECS Europe (Hetzner) pour améliorer inbox EU. Objectif : 99% inbox Europe</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">12</div><div class="txt"><strong>Whisper.cpp local</strong> — réactiver voice-to-text souverain sur S204 CPU. Objectif : transcription audio WEVIA</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">13</div><div class="txt"><strong>DeerFlow réactivation</strong> — restart quand RAM stabilisée. Objectif : workflow automation</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">14</div><div class="txt"><strong>S204 RAM upgrade</strong> — passer de 16GB à 32GB pour supporter Ollama + Docker + FPM sans crash. Objectif : stabilité définitive</div><div class="pri p2">P2</div></div>
<div class="plan-item"><div class="num">15</div><div class="txt"><strong>Sovereign API v4</strong> — ajouter Llama 4 Scout (Groq), DeepSeek-R1 (SambaNova), Qwen3-235B-think (Cerebras). Objectif : 15/15 providers</div><div class="pri p2">P2</div></div>
</div>
<!-- FOOTER -->
<div style="text-align:center;padding:20px 0;border-top:1px solid var(--border);margin-top:20px">
<div style="font-size:.65rem;color:var(--dim)">WEVAL Consulting · Casablanca · 14 avril 2026</div>
<div style="font-size:.6rem;color:var(--dim2);margin-top:4px">Session Opus directeur de projet · 346 tools · 13 providers · 141K HCPs · 0€ IA</div>
</div>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body>
</html>

View File

@@ -0,0 +1,165 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL Security Scanner — Secret Detection</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#0a0e1a;--card:#111827;--border:#1e293b;--red:#ef4444;--green:#10b981;--yellow:#f59e0b;--blue:#3b82f6;--text:#e2e8f0;--muted:#64748b;--mono:'JetBrains Mono',monospace;--font:'DM Sans',sans-serif}
*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--text);font-family:var(--font)}
.top{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:rgba(17,24,39,.95);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}
.logo{font-size:18px;font-weight:700;color:var(--red)}.logo span{color:var(--text);font-weight:400}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:20px 24px}
.kpi{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px;text-align:center}
.kpi .v{font-size:32px;font-weight:700;font-family:var(--mono)}.kpi .l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:4px}
.main{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:0 24px 24px}
.full{grid-column:1/-1}.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;animation:fadeIn .3s}
.card h3{font-size:14px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.badge{font-size:10px;padding:2px 8px;border-radius:99px;font-weight:500}
.bg{background:rgba(16,185,129,.2);color:var(--green)}.br{background:rgba(239,68,68,.2);color:var(--red)}.by{background:rgba(245,158,11,.2);color:var(--yellow)}.bb{background:rgba(59,130,246,.2);color:var(--blue)}
.tool{display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid var(--border)}
.tool:last-child{border:none}.tool .dot{width:10px;height:10px;border-radius:50%}.tool .name{font-weight:600;font-size:13px}.tool .desc{font-size:11px;color:var(--muted)}
.finding{padding:10px 12px;border-left:3px solid var(--yellow);background:rgba(245,158,11,.05);margin-bottom:6px;border-radius:0 6px 6px 0;font-size:12px}
.key{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);font-size:12px}
.key .kn{font-weight:600;font-family:var(--mono)}.key .kv{color:var(--green);font-size:10px}
.btn{padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:700;font-size:13px;transition:.2s}
.btn:hover{transform:translateY(-1px)}
.btn-red{background:var(--red);color:white}.btn-green{background:var(--green);color:white}.btn-blue{background:var(--blue);color:white}
#status{font-family:var(--mono);font-size:12px;padding:4px 12px;border-radius:6px}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.scanning{animation:pulse 1s infinite}
@media(max-width:768px){.main{grid-template-columns:1fr}}
</style></head><body>
<div class="top">
<div class="logo">🔐 WEVAL <span>Security Scanner</span></div>
<div style="display:flex;gap:8px;align-items:center">
<span id="status" class="bg">● IDLE</span>
<button class="btn btn-red" onclick="runScan()">🔍 Scan Now</button>
<button class="btn btn-blue" onclick="syncKeys()">🔄 Sync Keys</button>
</div>
</div>
<div class="kpis" id="kpis"></div>
<div class="main">
<div class="card"><h3>🛠️ Scanner Tools <span class="badge bb" id="tools-count">5</span></h3><div id="tools-list"></div></div>
<div class="card"><h3>⚠️ Findings <span class="badge by" id="findings-count">0</span></h3><div id="findings-list"></div></div>
<div class="card"><h3>🔑 Tracked Keys <span class="badge bg" id="keys-count">0</span></h3><div id="keys-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card"><h3>📁 Sensitive Files <span class="badge br" id="files-count">0</span></h3><div id="files-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card full"><h3>📋 Scan History</h3><div id="history" style="font-family:var(--mono);font-size:12px;color:var(--muted)">Loading...</div></div>
</div>
<script>
const API='/api/secret-scanner-api.php';
async function load(){
try{
const r=await fetch(API+'?action=results');
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
if(d.error){document.getElementById('history').textContent='No scan yet. Click Scan Now.';return}
// KPIs
const s=d.summary||{};
const kpis=[
{v:s.findings||0,l:'Findings',c:s.findings>5?'var(--red)':'var(--green)'},
{v:s.tools||5,l:'Tools Active',c:'var(--blue)'},
{v:(d.tools?.keyhacks?.tracked||0),l:'Keys Tracked',c:'var(--yellow)'},
{v:s.risk||'LOW',l:'Risk Level',c:s.risk==='HIGH'?'var(--red)':s.risk==='MEDIUM'?'var(--yellow)':'var(--green)'},
{v:d.repos||0,l:'Repos Scanned',c:'var(--blue)'},
{v:d.timestamp?.split('T')[1]?.substring(0,5)||'-',l:'Last Scan',c:'var(--muted)'}
];
document.getElementById('kpis').innerHTML=kpis.map(k=>'<div class="kpi"><div class="v" style="color:'+k.c+'">'+k.v+'</div><div class="l">'+k.l+'</div></div>').join('');
// Tools
const tools=[
{name:'TruffleHog',desc:'Git repo entropy + regex scanner',icon:'🐷',ok:d.tools?.trufflehog?.ok},
{name:'detect-secrets',desc:'Yelp secret detection engine',icon:'🔍',ok:d.tools?.['detect-secrets']?.ok!==false},
{name:'GitHub Dorking',desc:'Regex pattern search (AWS,Stripe,GitHub)',icon:'🕵️',ok:d.tools?.dorking?.ok},
{name:'KeyHacks',desc:'API key validation reference',icon:'🔑',ok:d.tools?.keyhacks?.ok},
{name:'shhgit Patterns',desc:'Sensitive file detection',icon:'🤫',ok:d.tools?.shhgit?.ok}
];
document.getElementById('tools-list').innerHTML=tools.map(t=>'<div class="tool"><div class="dot" style="background:'+(t.ok?'var(--green)':'var(--red)')+'"></div><div><div class="name">'+t.icon+' '+t.name+'</div><div class="desc">'+t.desc+'</div></div></div>').join('');
document.getElementById('tools-count').textContent=tools.filter(t=>t.ok).length+'/'+tools.length;
// Findings
const findings=d.findings||[];
document.getElementById('findings-count').textContent=findings.length;
document.getElementById('findings-list').innerHTML=findings.length?findings.map(f=>'<div class="finding"><strong>'+f.file+'</strong> — '+f.matches+' match(es)</div>').join(''):'<div style="color:var(--green);padding:20px;text-align:center">✅ No exposed secrets found</div>';
// Keys
const keys=d.tools?.keyhacks?.keys||[];
document.getElementById('keys-count').textContent=keys.length;
document.getElementById('keys-list').innerHTML=keys.map(k=>'<div class="key"><span class="kn">'+k+'</span><span class="kv">● tracked</span></div>').join('');
// Files
const files=d.tools?.shhgit?.files||[];
document.getElementById('files-count').textContent=files.length;
document.getElementById('files-list').innerHTML=files.map(f=>'<div style="padding:4px 8px;font-size:11px;font-family:var(--mono);border-bottom:1px solid var(--border)">📄 '+f+'</div>').join('')||'<div style="padding:20px;text-align:center;color:var(--muted)">No sensitive files outside secrets.env</div>';
// History
document.getElementById('history').textContent='Last scan: '+d.timestamp+' | Repos: '+d.repos+' | Risk: '+s.risk;
}catch(e){document.getElementById('history').textContent='Error: '+e.message}
}
async function runScan(){
document.getElementById('status').className='badge br scanning';
document.getElementById('status').textContent='● SCANNING...';
await fetch(API+'?action=scan');
setTimeout(()=>{document.getElementById('status').className='badge bg';document.getElementById('status').textContent='● DONE';load()},15000);
}
async function syncKeys(){
document.getElementById('status').textContent='● SYNCING...';
// Trigger key sync cron
await fetch(API+'?action=scan');
setTimeout(load,10000);
}
load();setInterval(load,60000);
</script>
<!-- WAVE 162 — Unified Pipeline Overlay -->
<div id="unifiedLiveOverlay" style="position:fixed;bottom:12px;right:12px;width:280px;max-height:calc(100vh - 120px);overflow-y:auto;background:linear-gradient(135deg,rgba(10,14,26,0.94),rgba(30,30,60,0.92));border:1px solid rgba(6,182,212,0.4);border-radius:10px;padding:10px;backdrop-filter:blur(14px);z-index:9999;font:600 9px Nunito,system-ui;color:#e2e8f0;box-shadow:0 4px 30px rgba(0,0,0,0.5)">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;padding-bottom:5px;border-bottom:1px solid rgba(100,116,139,0.3)">
<div style="font:900 10px Orbitron,system-ui;color:#06b6d4">🔴 <b id=closeLive style=cursor:pointer;margin-right:6px;color:gray onclick=unifiedLiveOverlay.remove()>x</b>UNIFIED LIVE</div>
<div id="ulo-ts" style="font-size:8px;color:#64748b"></div>
</div>
<div id="ulo-body">Loading...</div>
</div>
<script>
(function(){
const U='/api/weval-unified-pipeline.php';
async function tick(){
try{
const r=await fetch(U,{cache:'no-cache'});
if(!r.ok) return;
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
const body=document.getElementById('ulo-body');
const ts=document.getElementById('ulo-ts');
if(!body) return;
const h=d.l99.health||'?';
const hc={GREEN:'#10b981',YELLOW:'#f59e0b',RED:'#ef4444'}[h]||'#64748b';
let html='<div style="background:'+hc+'15;border-left:3px solid '+hc+';padding:5px;margin-bottom:5px;border-radius:3px"><b style="color:'+hc+'">● '+h+'</b> L99 <b>'+d.l99.pass+'/'+d.l99.total+'</b><br><span style="color:#94a3b8">Disk '+d.system.disk_pct+'% Docker '+d.system.docker_count+' Crons '+d.system.cron_count+'</span></div>';
html+='<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:5px"><div style="background:rgba(6,182,212,0.1);border:1px solid rgba(6,182,212,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#06b6d4">SOVEREIGN</div><b>'+d.providers.count+'</b> providers<br><b>'+d.ollama.models+'</b> Ollama<br><b>'+d.qdrant.collections.length+'</b> Qdrant</div><div style="background:rgba(139,92,246,0.1);border:1px solid rgba(139,92,246,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#8b5cf6">PAPERCLIP</div><b>'+d.goals.length+'</b> goals<br><b>'+d.projects.length+'</b> projects<br><b>'+d.routines.length+'</b> routines</div></div>';
html+='<div style="background:rgba(245,158,11,0.1);border:1px solid rgba(245,158,11,0.3);border-radius:4px;padding:4px;margin-bottom:5px"><div style="font:800 8px Orbitron;color:#f59e0b">ETHICA</div><b>'+(d.ethica.hcps_validated/1000).toFixed(0)+'K</b> HCPs '+d.ethica.coverage.join(' ')+'</div>';
const rpa=d.routines_per_agent||{};
const top=Object.entries(rpa).sort((a,b)=>b[1]-a[1]).slice(0,5);
if(top.length){
html+='<div style="font:800 8px Orbitron;color:#10b981;margin:4px 0">TOP AGENTS</div>';
top.forEach(([n,c])=>{html+='<div style="display:flex;justify-content:space-between;padding:1px 3px;background:rgba(16,185,129,0.05);border-radius:2px;margin-bottom:1px"><span>'+n+'</span><b style="color:#10b981">'+c+'</b></div>';});
}
html+='<div style="margin-top:5px;padding-top:4px;border-top:1px solid rgba(100,116,139,0.3);font-size:8px;color:#64748b;text-align:center"><a href="/wevia-master.html" style="color:#06b6d4">Master</a> · <a href="/agents-archi.html" style="color:#06b6d4">Archi</a> · <a href="/wevia-meeting-rooms.html" style="color:#06b6d4">Rooms</a> · <a href="https://paperclip.weval-consulting.com" style="color:#06b6d4" target="_blank">Paperclip</a></div>';
body.innerHTML=html;
if(ts) ts.textContent=new Date().toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit',second:'2-digit'});
}catch(e){}
}
setTimeout(tick,1500);setInterval(tick,30000);
})();
</script>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,165 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL Security Scanner — Secret Detection</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#0a0e1a;--card:#111827;--border:#1e293b;--red:#ef4444;--green:#10b981;--yellow:#f59e0b;--blue:#3b82f6;--text:#e2e8f0;--muted:#64748b;--mono:'JetBrains Mono',monospace;--font:'DM Sans',sans-serif}
*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--text);font-family:var(--font)}
.top{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:rgba(17,24,39,.95);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}
.logo{font-size:18px;font-weight:700;color:var(--red)}.logo span{color:var(--text);font-weight:400}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:20px 24px}
.kpi{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px;text-align:center}
.kpi .v{font-size:32px;font-weight:700;font-family:var(--mono)}.kpi .l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:4px}
.main{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:0 24px 24px}
.full{grid-column:1/-1}.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;animation:fadeIn .3s}
.card h3{font-size:14px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.badge{font-size:10px;padding:2px 8px;border-radius:99px;font-weight:500}
.bg{background:rgba(16,185,129,.2);color:var(--green)}.br{background:rgba(239,68,68,.2);color:var(--red)}.by{background:rgba(245,158,11,.2);color:var(--yellow)}.bb{background:rgba(59,130,246,.2);color:var(--blue)}
.tool{display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid var(--border)}
.tool:last-child{border:none}.tool .dot{width:10px;height:10px;border-radius:50%}.tool .name{font-weight:600;font-size:13px}.tool .desc{font-size:11px;color:var(--muted)}
.finding{padding:10px 12px;border-left:3px solid var(--yellow);background:rgba(245,158,11,.05);margin-bottom:6px;border-radius:0 6px 6px 0;font-size:12px}
.key{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);font-size:12px}
.key .kn{font-weight:600;font-family:var(--mono)}.key .kv{color:var(--green);font-size:10px}
.btn{padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:700;font-size:13px;transition:.2s}
.btn:hover{transform:translateY(-1px)}
.btn-red{background:var(--red);color:white}.btn-green{background:var(--green);color:white}.btn-blue{background:var(--blue);color:white}
#status{font-family:var(--mono);font-size:12px;padding:4px 12px;border-radius:6px}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.scanning{animation:pulse 1s infinite}
@media(max-width:768px){.main{grid-template-columns:1fr}}
</style></head><body>
<div class="top">
<div class="logo">🔐 WEVAL <span>Security Scanner</span></div>
<div style="display:flex;gap:8px;align-items:center">
<span id="status" class="bg">● IDLE</span>
<button class="btn btn-red" onclick="runScan()">🔍 Scan Now</button>
<button class="btn btn-blue" onclick="syncKeys()">🔄 Sync Keys</button>
</div>
</div>
<div class="kpis" id="kpis"></div>
<div class="main">
<div class="card"><h3>🛠️ Scanner Tools <span class="badge bb" id="tools-count">5</span></h3><div id="tools-list"></div></div>
<div class="card"><h3>⚠️ Findings <span class="badge by" id="findings-count">0</span></h3><div id="findings-list"></div></div>
<div class="card"><h3>🔑 Tracked Keys <span class="badge bg" id="keys-count">0</span></h3><div id="keys-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card"><h3>📁 Sensitive Files <span class="badge br" id="files-count">0</span></h3><div id="files-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card full"><h3>📋 Scan History</h3><div id="history" style="font-family:var(--mono);font-size:12px;color:var(--muted)">Loading...</div></div>
</div>
<script>
const API='/api/secret-scanner-api.php';
async function load(){
try{
const r=await fetch(API+'?action=results');
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
if(d.error){document.getElementById('history').textContent='No scan yet. Click Scan Now.';return}
// KPIs
const s=d.summary||{};
const kpis=[
{v:s.findings||0,l:'Findings',c:s.findings>5?'var(--red)':'var(--green)'},
{v:s.tools||5,l:'Tools Active',c:'var(--blue)'},
{v:(d.tools?.keyhacks?.tracked||0),l:'Keys Tracked',c:'var(--yellow)'},
{v:s.risk||'LOW',l:'Risk Level',c:s.risk==='HIGH'?'var(--red)':s.risk==='MEDIUM'?'var(--yellow)':'var(--green)'},
{v:d.repos||0,l:'Repos Scanned',c:'var(--blue)'},
{v:d.timestamp?.split('T')[1]?.substring(0,5)||'-',l:'Last Scan',c:'var(--muted)'}
];
document.getElementById('kpis').innerHTML=kpis.map(k=>'<div class="kpi"><div class="v" style="color:'+k.c+'">'+k.v+'</div><div class="l">'+k.l+'</div></div>').join('');
// Tools
const tools=[
{name:'TruffleHog',desc:'Git repo entropy + regex scanner',icon:'🐷',ok:d.tools?.trufflehog?.ok},
{name:'detect-secrets',desc:'Yelp secret detection engine',icon:'🔍',ok:d.tools?.['detect-secrets']?.ok!==false},
{name:'GitHub Dorking',desc:'Regex pattern search (AWS,Stripe,GitHub)',icon:'🕵️',ok:d.tools?.dorking?.ok},
{name:'KeyHacks',desc:'API key validation reference',icon:'🔑',ok:d.tools?.keyhacks?.ok},
{name:'shhgit Patterns',desc:'Sensitive file detection',icon:'🤫',ok:d.tools?.shhgit?.ok}
];
document.getElementById('tools-list').innerHTML=tools.map(t=>'<div class="tool"><div class="dot" style="background:'+(t.ok?'var(--green)':'var(--red)')+'"></div><div><div class="name">'+t.icon+' '+t.name+'</div><div class="desc">'+t.desc+'</div></div></div>').join('');
document.getElementById('tools-count').textContent=tools.filter(t=>t.ok).length+'/'+tools.length;
// Findings
const findings=d.findings||[];
document.getElementById('findings-count').textContent=findings.length;
document.getElementById('findings-list').innerHTML=findings.length?findings.map(f=>'<div class="finding"><strong>'+f.file+'</strong> — '+f.matches+' match(es)</div>').join(''):'<div style="color:var(--green);padding:20px;text-align:center">✅ No exposed secrets found</div>';
// Keys
const keys=d.tools?.keyhacks?.keys||[];
document.getElementById('keys-count').textContent=keys.length;
document.getElementById('keys-list').innerHTML=keys.map(k=>'<div class="key"><span class="kn">'+k+'</span><span class="kv">● tracked</span></div>').join('');
// Files
const files=d.tools?.shhgit?.files||[];
document.getElementById('files-count').textContent=files.length;
document.getElementById('files-list').innerHTML=files.map(f=>'<div style="padding:4px 8px;font-size:11px;font-family:var(--mono);border-bottom:1px solid var(--border)">📄 '+f+'</div>').join('')||'<div style="padding:20px;text-align:center;color:var(--muted)">No sensitive files outside secrets.env</div>';
// History
document.getElementById('history').textContent='Last scan: '+d.timestamp+' | Repos: '+d.repos+' | Risk: '+s.risk;
}catch(e){document.getElementById('history').textContent='Error: '+e.message}
}
async function runScan(){
document.getElementById('status').className='badge br scanning';
document.getElementById('status').textContent='● SCANNING...';
await fetch(API+'?action=scan');
setTimeout(()=>{document.getElementById('status').className='badge bg';document.getElementById('status').textContent='● DONE';load()},15000);
}
async function syncKeys(){
document.getElementById('status').textContent='● SYNCING...';
// Trigger key sync cron
await fetch(API+'?action=scan');
setTimeout(load,10000);
}
load();setInterval(load,60000);
</script>
<!-- WAVE 162 — Unified Pipeline Overlay -->
<div id="unifiedLiveOverlay" style="position:fixed;bottom:12px;right:12px;width:280px;max-height:calc(100vh - 120px);overflow-y:auto;background:linear-gradient(135deg,rgba(10,14,26,0.94),rgba(30,30,60,0.92));border:1px solid rgba(6,182,212,0.4);border-radius:10px;padding:10px;backdrop-filter:blur(14px);z-index:9999;font:600 9px Nunito,system-ui;color:#e2e8f0;box-shadow:0 4px 30px rgba(0,0,0,0.5)">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;padding-bottom:5px;border-bottom:1px solid rgba(100,116,139,0.3)">
<div style="font:900 10px Orbitron,system-ui;color:#06b6d4">🔴 <b id=closeLive style=cursor:pointer;margin-right:6px;color:gray onclick=unifiedLiveOverlay.remove()>x</b>UNIFIED LIVE</div>
<div id="ulo-ts" style="font-size:8px;color:#64748b"></div>
</div>
<div id="ulo-body">Loading...</div>
</div>
<script>
(function(){
const U='/api/weval-unified-pipeline.php';
async function tick(){
try{
const r=await fetch(U,{cache:'no-cache'});
if(!r.ok) return;
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
const body=document.getElementById('ulo-body');
const ts=document.getElementById('ulo-ts');
if(!body) return;
const h=d.l99.health||'?';
const hc={GREEN:'#10b981',YELLOW:'#f59e0b',RED:'#ef4444'}[h]||'#64748b';
let html='<div style="background:'+hc+'15;border-left:3px solid '+hc+';padding:5px;margin-bottom:5px;border-radius:3px"><b style="color:'+hc+'">● '+h+'</b> L99 <b>'+d.l99.pass+'/'+d.l99.total+'</b><br><span style="color:#94a3b8">Disk '+d.system.disk_pct+'% Docker '+d.system.docker_count+' Crons '+d.system.cron_count+'</span></div>';
html+='<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:5px"><div style="background:rgba(6,182,212,0.1);border:1px solid rgba(6,182,212,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#06b6d4">SOVEREIGN</div><b>'+d.providers.count+'</b> providers<br><b>'+d.ollama.models+'</b> Ollama<br><b>'+d.qdrant.collections.length+'</b> Qdrant</div><div style="background:rgba(139,92,246,0.1);border:1px solid rgba(139,92,246,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#8b5cf6">PAPERCLIP</div><b>'+d.goals.length+'</b> goals<br><b>'+d.projects.length+'</b> projects<br><b>'+d.routines.length+'</b> routines</div></div>';
html+='<div style="background:rgba(245,158,11,0.1);border:1px solid rgba(245,158,11,0.3);border-radius:4px;padding:4px;margin-bottom:5px"><div style="font:800 8px Orbitron;color:#f59e0b">ETHICA</div><b>'+(d.ethica.hcps_validated/1000).toFixed(0)+'K</b> HCPs '+d.ethica.coverage.join(' ')+'</div>';
const rpa=d.routines_per_agent||{};
const top=Object.entries(rpa).sort((a,b)=>b[1]-a[1]).slice(0,5);
if(top.length){
html+='<div style="font:800 8px Orbitron;color:#10b981;margin:4px 0">TOP AGENTS</div>';
top.forEach(([n,c])=>{html+='<div style="display:flex;justify-content:space-between;padding:1px 3px;background:rgba(16,185,129,0.05);border-radius:2px;margin-bottom:1px"><span>'+n+'</span><b style="color:#10b981">'+c+'</b></div>';});
}
html+='<div style="margin-top:5px;padding-top:4px;border-top:1px solid rgba(100,116,139,0.3);font-size:8px;color:#64748b;text-align:center"><a href="/wevia-master.html" style="color:#06b6d4">Master</a> · <a href="/agents-archi.html" style="color:#06b6d4">Archi</a> · <a href="/wevia-meeting-rooms.html" style="color:#06b6d4">Rooms</a> · <a href="https://paperclip.weval-consulting.com" style="color:#06b6d4" target="_blank">Paperclip</a></div>';
body.innerHTML=html;
if(ts) ts.textContent=new Date().toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit',second:'2-digit'});
}catch(e){}
}
setTimeout(tick,1500);setInterval(tick,30000);
})();
</script>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,165 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL Security Scanner — Secret Detection</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#0a0e1a;--card:#111827;--border:#1e293b;--red:#ef4444;--green:#10b981;--yellow:#f59e0b;--blue:#3b82f6;--text:#e2e8f0;--muted:#64748b;--mono:'JetBrains Mono',monospace;--font:'DM Sans',sans-serif}
*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--text);font-family:var(--font)}
.top{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:rgba(17,24,39,.95);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}
.logo{font-size:18px;font-weight:700;color:var(--red)}.logo span{color:var(--text);font-weight:400}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:20px 24px}
.kpi{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px;text-align:center}
.kpi .v{font-size:32px;font-weight:700;font-family:var(--mono)}.kpi .l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:4px}
.main{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:0 24px 24px}
.full{grid-column:1/-1}.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;animation:fadeIn .3s}
.card h3{font-size:14px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.badge{font-size:10px;padding:2px 8px;border-radius:99px;font-weight:500}
.bg{background:rgba(16,185,129,.2);color:var(--green)}.br{background:rgba(239,68,68,.2);color:var(--red)}.by{background:rgba(245,158,11,.2);color:var(--yellow)}.bb{background:rgba(59,130,246,.2);color:var(--blue)}
.tool{display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid var(--border)}
.tool:last-child{border:none}.tool .dot{width:10px;height:10px;border-radius:50%}.tool .name{font-weight:600;font-size:13px}.tool .desc{font-size:11px;color:var(--muted)}
.finding{padding:10px 12px;border-left:3px solid var(--yellow);background:rgba(245,158,11,.05);margin-bottom:6px;border-radius:0 6px 6px 0;font-size:12px}
.key{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);font-size:12px}
.key .kn{font-weight:600;font-family:var(--mono)}.key .kv{color:var(--green);font-size:10px}
.btn{padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:700;font-size:13px;transition:.2s}
.btn:hover{transform:translateY(-1px)}
.btn-red{background:var(--red);color:white}.btn-green{background:var(--green);color:white}.btn-blue{background:var(--blue);color:white}
#status{font-family:var(--mono);font-size:12px;padding:4px 12px;border-radius:6px}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.scanning{animation:pulse 1s infinite}
@media(max-width:768px){.main{grid-template-columns:1fr}}
</style></head><body>
<div class="top">
<div class="logo">🔐 WEVAL <span>Security Scanner</span></div>
<div style="display:flex;gap:8px;align-items:center">
<span id="status" class="bg">● IDLE</span>
<button class="btn btn-red" onclick="runScan()">🔍 Scan Now</button>
<button class="btn btn-blue" onclick="syncKeys()">🔄 Sync Keys</button>
</div>
</div>
<div class="kpis" id="kpis"></div>
<div class="main">
<div class="card"><h3>🛠️ Scanner Tools <span class="badge bb" id="tools-count">5</span></h3><div id="tools-list"></div></div>
<div class="card"><h3>⚠️ Findings <span class="badge by" id="findings-count">0</span></h3><div id="findings-list"></div></div>
<div class="card"><h3>🔑 Tracked Keys <span class="badge bg" id="keys-count">0</span></h3><div id="keys-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card"><h3>📁 Sensitive Files <span class="badge br" id="files-count">0</span></h3><div id="files-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card full"><h3>📋 Scan History</h3><div id="history" style="font-family:var(--mono);font-size:12px;color:var(--muted)">Loading...</div></div>
</div>
<script>
const API='/api/secret-scanner-api.php';
async function load(){
try{
const r=await fetch(API+'?action=results');
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
if(d.error){document.getElementById('history').textContent='No scan yet. Click Scan Now.';return}
// KPIs
const s=d.summary||{};
const kpis=[
{v:s.findings||0,l:'Findings',c:s.findings>5?'var(--red)':'var(--green)'},
{v:s.tools||5,l:'Tools Active',c:'var(--blue)'},
{v:(d.tools?.keyhacks?.tracked||0),l:'Keys Tracked',c:'var(--yellow)'},
{v:s.risk||'LOW',l:'Risk Level',c:s.risk==='HIGH'?'var(--red)':s.risk==='MEDIUM'?'var(--yellow)':'var(--green)'},
{v:d.repos||0,l:'Repos Scanned',c:'var(--blue)'},
{v:d.timestamp?.split('T')[1]?.substring(0,5)||'-',l:'Last Scan',c:'var(--muted)'}
];
document.getElementById('kpis').innerHTML=kpis.map(k=>'<div class="kpi"><div class="v" style="color:'+k.c+'">'+k.v+'</div><div class="l">'+k.l+'</div></div>').join('');
// Tools
const tools=[
{name:'TruffleHog',desc:'Git repo entropy + regex scanner',icon:'🐷',ok:d.tools?.trufflehog?.ok},
{name:'detect-secrets',desc:'Yelp secret detection engine',icon:'🔍',ok:d.tools?.['detect-secrets']?.ok!==false},
{name:'GitHub Dorking',desc:'Regex pattern search (AWS,Stripe,GitHub)',icon:'🕵️',ok:d.tools?.dorking?.ok},
{name:'KeyHacks',desc:'API key validation reference',icon:'🔑',ok:d.tools?.keyhacks?.ok},
{name:'shhgit Patterns',desc:'Sensitive file detection',icon:'🤫',ok:d.tools?.shhgit?.ok}
];
document.getElementById('tools-list').innerHTML=tools.map(t=>'<div class="tool"><div class="dot" style="background:'+(t.ok?'var(--green)':'var(--red)')+'"></div><div><div class="name">'+t.icon+' '+t.name+'</div><div class="desc">'+t.desc+'</div></div></div>').join('');
document.getElementById('tools-count').textContent=tools.filter(t=>t.ok).length+'/'+tools.length;
// Findings
const findings=d.findings||[];
document.getElementById('findings-count').textContent=findings.length;
document.getElementById('findings-list').innerHTML=findings.length?findings.map(f=>'<div class="finding"><strong>'+f.file+'</strong> — '+f.matches+' match(es)</div>').join(''):'<div style="color:var(--green);padding:20px;text-align:center">✅ No exposed secrets found</div>';
// Keys
const keys=d.tools?.keyhacks?.keys||[];
document.getElementById('keys-count').textContent=keys.length;
document.getElementById('keys-list').innerHTML=keys.map(k=>'<div class="key"><span class="kn">'+k+'</span><span class="kv">● tracked</span></div>').join('');
// Files
const files=d.tools?.shhgit?.files||[];
document.getElementById('files-count').textContent=files.length;
document.getElementById('files-list').innerHTML=files.map(f=>'<div style="padding:4px 8px;font-size:11px;font-family:var(--mono);border-bottom:1px solid var(--border)">📄 '+f+'</div>').join('')||'<div style="padding:20px;text-align:center;color:var(--muted)">No sensitive files outside secrets.env</div>';
// History
document.getElementById('history').textContent='Last scan: '+d.timestamp+' | Repos: '+d.repos+' | Risk: '+s.risk;
}catch(e){document.getElementById('history').textContent='Error: '+e.message}
}
async function runScan(){
document.getElementById('status').className='badge br scanning';
document.getElementById('status').textContent='● SCANNING...';
await fetch(API+'?action=scan');
setTimeout(()=>{document.getElementById('status').className='badge bg';document.getElementById('status').textContent='● DONE';load()},15000);
}
async function syncKeys(){
document.getElementById('status').textContent='● SYNCING...';
// Trigger key sync cron
await fetch(API+'?action=scan');
setTimeout(load,10000);
}
load();setInterval(load,60000);
</script>
<!-- WAVE 162 — Unified Pipeline Overlay -->
<div id="unifiedLiveOverlay" style="position:fixed;bottom:12px;right:12px;width:280px;max-height:calc(100vh - 120px);overflow-y:auto;background:linear-gradient(135deg,rgba(10,14,26,0.94),rgba(30,30,60,0.92));border:1px solid rgba(6,182,212,0.4);border-radius:10px;padding:10px;backdrop-filter:blur(14px);z-index:9999;font:600 9px Nunito,system-ui;color:#e2e8f0;box-shadow:0 4px 30px rgba(0,0,0,0.5)">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;padding-bottom:5px;border-bottom:1px solid rgba(100,116,139,0.3)">
<div style="font:900 10px Orbitron,system-ui;color:#06b6d4">🔴 <b id=closeLive style=cursor:pointer;margin-right:6px;color:gray onclick=unifiedLiveOverlay.remove()>x</b>UNIFIED LIVE</div>
<div id="ulo-ts" style="font-size:8px;color:#64748b"></div>
</div>
<div id="ulo-body">Loading...</div>
</div>
<script>
(function(){
const U='/api/weval-unified-pipeline.php';
async function tick(){
try{
const r=await fetch(U,{cache:'no-cache'});
if(!r.ok) return;
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
const body=document.getElementById('ulo-body');
const ts=document.getElementById('ulo-ts');
if(!body) return;
const h=d.l99.health||'?';
const hc={GREEN:'#10b981',YELLOW:'#f59e0b',RED:'#ef4444'}[h]||'#64748b';
let html='<div style="background:'+hc+'15;border-left:3px solid '+hc+';padding:5px;margin-bottom:5px;border-radius:3px"><b style="color:'+hc+'">● '+h+'</b> L99 <b>'+d.l99.pass+'/'+d.l99.total+'</b><br><span style="color:#94a3b8">Disk '+d.system.disk_pct+'% Docker '+d.system.docker_count+' Crons '+d.system.cron_count+'</span></div>';
html+='<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:5px"><div style="background:rgba(6,182,212,0.1);border:1px solid rgba(6,182,212,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#06b6d4">SOVEREIGN</div><b>'+d.providers.count+'</b> providers<br><b>'+d.ollama.models+'</b> Ollama<br><b>'+d.qdrant.collections.length+'</b> Qdrant</div><div style="background:rgba(139,92,246,0.1);border:1px solid rgba(139,92,246,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#8b5cf6">PAPERCLIP</div><b>'+d.goals.length+'</b> goals<br><b>'+d.projects.length+'</b> projects<br><b>'+d.routines.length+'</b> routines</div></div>';
html+='<div style="background:rgba(245,158,11,0.1);border:1px solid rgba(245,158,11,0.3);border-radius:4px;padding:4px;margin-bottom:5px"><div style="font:800 8px Orbitron;color:#f59e0b">ETHICA</div><b>'+(d.ethica.hcps_validated/1000).toFixed(0)+'K</b> HCPs '+d.ethica.coverage.join(' ')+'</div>';
const rpa=d.routines_per_agent||{};
const top=Object.entries(rpa).sort((a,b)=>b[1]-a[1]).slice(0,5);
if(top.length){
html+='<div style="font:800 8px Orbitron;color:#10b981;margin:4px 0">TOP AGENTS</div>';
top.forEach(([n,c])=>{html+='<div style="display:flex;justify-content:space-between;padding:1px 3px;background:rgba(16,185,129,0.05);border-radius:2px;margin-bottom:1px"><span>'+n+'</span><b style="color:#10b981">'+c+'</b></div>';});
}
html+='<div style="margin-top:5px;padding-top:4px;border-top:1px solid rgba(100,116,139,0.3);font-size:8px;color:#64748b;text-align:center"><a href="/wevia-master.html" style="color:#06b6d4">Master</a> · <a href="/agents-archi.html" style="color:#06b6d4">Archi</a> · <a href="/wevia-meeting-rooms.html" style="color:#06b6d4">Rooms</a> · <a href="https://paperclip.weval-consulting.com" style="color:#06b6d4" target="_blank">Paperclip</a></div>';
body.innerHTML=html;
if(ts) ts.textContent=new Date().toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit',second:'2-digit'});
}catch(e){}
}
setTimeout(tick,1500);setInterval(tick,30000);
})();
</script>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,165 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL Security Scanner — Secret Detection</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#0a0e1a;--card:#111827;--border:#1e293b;--red:#ef4444;--green:#10b981;--yellow:#f59e0b;--blue:#3b82f6;--text:#e2e8f0;--muted:#64748b;--mono:'JetBrains Mono',monospace;--font:'DM Sans',sans-serif}
*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--text);font-family:var(--font)}
.top{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:rgba(17,24,39,.95);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}
.logo{font-size:18px;font-weight:700;color:var(--red)}.logo span{color:var(--text);font-weight:400}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:20px 24px}
.kpi{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px;text-align:center}
.kpi .v{font-size:32px;font-weight:700;font-family:var(--mono)}.kpi .l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:4px}
.main{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:0 24px 24px}
.full{grid-column:1/-1}.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;animation:fadeIn .3s}
.card h3{font-size:14px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.badge{font-size:10px;padding:2px 8px;border-radius:99px;font-weight:500}
.bg{background:rgba(16,185,129,.2);color:var(--green)}.br{background:rgba(239,68,68,.2);color:var(--red)}.by{background:rgba(245,158,11,.2);color:var(--yellow)}.bb{background:rgba(59,130,246,.2);color:var(--blue)}
.tool{display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid var(--border)}
.tool:last-child{border:none}.tool .dot{width:10px;height:10px;border-radius:50%}.tool .name{font-weight:600;font-size:13px}.tool .desc{font-size:11px;color:var(--muted)}
.finding{padding:10px 12px;border-left:3px solid var(--yellow);background:rgba(245,158,11,.05);margin-bottom:6px;border-radius:0 6px 6px 0;font-size:12px}
.key{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);font-size:12px}
.key .kn{font-weight:600;font-family:var(--mono)}.key .kv{color:var(--green);font-size:10px}
.btn{padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:700;font-size:13px;transition:.2s}
.btn:hover{transform:translateY(-1px)}
.btn-red{background:var(--red);color:white}.btn-green{background:var(--green);color:white}.btn-blue{background:var(--blue);color:white}
#status{font-family:var(--mono);font-size:12px;padding:4px 12px;border-radius:6px}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.scanning{animation:pulse 1s infinite}
@media(max-width:768px){.main{grid-template-columns:1fr}}
</style></head><body>
<div class="top">
<div class="logo">🔐 WEVAL <span>Security Scanner</span></div>
<div style="display:flex;gap:8px;align-items:center">
<span id="status" class="bg">● IDLE</span>
<button class="btn btn-red" onclick="runScan()">🔍 Scan Now</button>
<button class="btn btn-blue" onclick="syncKeys()">🔄 Sync Keys</button>
</div>
</div>
<div class="kpis" id="kpis"></div>
<div class="main">
<div class="card"><h3>🛠️ Scanner Tools <span class="badge bb" id="tools-count">5</span></h3><div id="tools-list"></div></div>
<div class="card"><h3>⚠️ Findings <span class="badge by" id="findings-count">0</span></h3><div id="findings-list"></div></div>
<div class="card"><h3>🔑 Tracked Keys <span class="badge bg" id="keys-count">0</span></h3><div id="keys-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card"><h3>📁 Sensitive Files <span class="badge br" id="files-count">0</span></h3><div id="files-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card full"><h3>📋 Scan History</h3><div id="history" style="font-family:var(--mono);font-size:12px;color:var(--muted)">Loading...</div></div>
</div>
<script>
const API='/api/secret-scanner-api.php';
async function load(){
try{
const r=await fetch(API+'?action=results');
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
if(d.error){document.getElementById('history').textContent='No scan yet. Click Scan Now.';return}
// KPIs
const s=d.summary||{};
const kpis=[
{v:s.findings||0,l:'Findings',c:s.findings>5?'var(--red)':'var(--green)'},
{v:s.tools||5,l:'Tools Active',c:'var(--blue)'},
{v:(d.tools?.keyhacks?.tracked||0),l:'Keys Tracked',c:'var(--yellow)'},
{v:s.risk||'LOW',l:'Risk Level',c:s.risk==='HIGH'?'var(--red)':s.risk==='MEDIUM'?'var(--yellow)':'var(--green)'},
{v:d.repos||0,l:'Repos Scanned',c:'var(--blue)'},
{v:d.timestamp?.split('T')[1]?.substring(0,5)||'-',l:'Last Scan',c:'var(--muted)'}
];
document.getElementById('kpis').innerHTML=kpis.map(k=>'<div class="kpi"><div class="v" style="color:'+k.c+'">'+k.v+'</div><div class="l">'+k.l+'</div></div>').join('');
// Tools
const tools=[
{name:'TruffleHog',desc:'Git repo entropy + regex scanner',icon:'🐷',ok:d.tools?.trufflehog?.ok},
{name:'detect-secrets',desc:'Yelp secret detection engine',icon:'🔍',ok:d.tools?.['detect-secrets']?.ok!==false},
{name:'GitHub Dorking',desc:'Regex pattern search (AWS,Stripe,GitHub)',icon:'🕵️',ok:d.tools?.dorking?.ok},
{name:'KeyHacks',desc:'API key validation reference',icon:'🔑',ok:d.tools?.keyhacks?.ok},
{name:'shhgit Patterns',desc:'Sensitive file detection',icon:'🤫',ok:d.tools?.shhgit?.ok}
];
document.getElementById('tools-list').innerHTML=tools.map(t=>'<div class="tool"><div class="dot" style="background:'+(t.ok?'var(--green)':'var(--red)')+'"></div><div><div class="name">'+t.icon+' '+t.name+'</div><div class="desc">'+t.desc+'</div></div></div>').join('');
document.getElementById('tools-count').textContent=tools.filter(t=>t.ok).length+'/'+tools.length;
// Findings
const findings=d.findings||[];
document.getElementById('findings-count').textContent=findings.length;
document.getElementById('findings-list').innerHTML=findings.length?findings.map(f=>'<div class="finding"><strong>'+f.file+'</strong> — '+f.matches+' match(es)</div>').join(''):'<div style="color:var(--green);padding:20px;text-align:center">✅ No exposed secrets found</div>';
// Keys
const keys=d.tools?.keyhacks?.keys||[];
document.getElementById('keys-count').textContent=keys.length;
document.getElementById('keys-list').innerHTML=keys.map(k=>'<div class="key"><span class="kn">'+k+'</span><span class="kv">● tracked</span></div>').join('');
// Files
const files=d.tools?.shhgit?.files||[];
document.getElementById('files-count').textContent=files.length;
document.getElementById('files-list').innerHTML=files.map(f=>'<div style="padding:4px 8px;font-size:11px;font-family:var(--mono);border-bottom:1px solid var(--border)">📄 '+f+'</div>').join('')||'<div style="padding:20px;text-align:center;color:var(--muted)">No sensitive files outside secrets.env</div>';
// History
document.getElementById('history').textContent='Last scan: '+d.timestamp+' | Repos: '+d.repos+' | Risk: '+s.risk;
}catch(e){document.getElementById('history').textContent='Error: '+e.message}
}
async function runScan(){
document.getElementById('status').className='badge br scanning';
document.getElementById('status').textContent='● SCANNING...';
await fetch(API+'?action=scan');
setTimeout(()=>{document.getElementById('status').className='badge bg';document.getElementById('status').textContent='● DONE';load()},15000);
}
async function syncKeys(){
document.getElementById('status').textContent='● SYNCING...';
// Trigger key sync cron
await fetch(API+'?action=scan');
setTimeout(load,10000);
}
load();setInterval(load,60000);
</script>
<!-- WAVE 162 — Unified Pipeline Overlay -->
<div id="unifiedLiveOverlay" style="position:fixed;bottom:12px;right:12px;width:280px;max-height:calc(100vh - 120px);overflow-y:auto;background:linear-gradient(135deg,rgba(10,14,26,0.94),rgba(30,30,60,0.92));border:1px solid rgba(6,182,212,0.4);border-radius:10px;padding:10px;backdrop-filter:blur(14px);z-index:9999;font:600 9px Nunito,system-ui;color:#e2e8f0;box-shadow:0 4px 30px rgba(0,0,0,0.5)">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;padding-bottom:5px;border-bottom:1px solid rgba(100,116,139,0.3)">
<div style="font:900 10px Orbitron,system-ui;color:#06b6d4">🔴 <b id=closeLive style=cursor:pointer;margin-right:6px;color:gray onclick=unifiedLiveOverlay.remove()>x</b>UNIFIED LIVE</div>
<div id="ulo-ts" style="font-size:8px;color:#64748b"></div>
</div>
<div id="ulo-body">Loading...</div>
</div>
<script>
(function(){
const U='/api/weval-unified-pipeline.php';
async function tick(){
try{
const r=await fetch(U,{cache:'no-cache'});
if(!r.ok) return;
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
const body=document.getElementById('ulo-body');
const ts=document.getElementById('ulo-ts');
if(!body) return;
const h=d.l99.health||'?';
const hc={GREEN:'#10b981',YELLOW:'#f59e0b',RED:'#ef4444'}[h]||'#64748b';
let html='<div style="background:'+hc+'15;border-left:3px solid '+hc+';padding:5px;margin-bottom:5px;border-radius:3px"><b style="color:'+hc+'">● '+h+'</b> L99 <b>'+d.l99.pass+'/'+d.l99.total+'</b><br><span style="color:#94a3b8">Disk '+d.system.disk_pct+'% Docker '+d.system.docker_count+' Crons '+d.system.cron_count+'</span></div>';
html+='<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:5px"><div style="background:rgba(6,182,212,0.1);border:1px solid rgba(6,182,212,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#06b6d4">SOVEREIGN</div><b>'+d.providers.count+'</b> providers<br><b>'+d.ollama.models+'</b> Ollama<br><b>'+d.qdrant.collections.length+'</b> Qdrant</div><div style="background:rgba(139,92,246,0.1);border:1px solid rgba(139,92,246,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#8b5cf6">PAPERCLIP</div><b>'+d.goals.length+'</b> goals<br><b>'+d.projects.length+'</b> projects<br><b>'+d.routines.length+'</b> routines</div></div>';
html+='<div style="background:rgba(245,158,11,0.1);border:1px solid rgba(245,158,11,0.3);border-radius:4px;padding:4px;margin-bottom:5px"><div style="font:800 8px Orbitron;color:#f59e0b">ETHICA</div><b>'+(d.ethica.hcps_validated/1000).toFixed(0)+'K</b> HCPs '+d.ethica.coverage.join(' ')+'</div>';
const rpa=d.routines_per_agent||{};
const top=Object.entries(rpa).sort((a,b)=>b[1]-a[1]).slice(0,5);
if(top.length){
html+='<div style="font:800 8px Orbitron;color:#10b981;margin:4px 0">TOP AGENTS</div>';
top.forEach(([n,c])=>{html+='<div style="display:flex;justify-content:space-between;padding:1px 3px;background:rgba(16,185,129,0.05);border-radius:2px;margin-bottom:1px"><span>'+n+'</span><b style="color:#10b981">'+c+'</b></div>';});
}
html+='<div style="margin-top:5px;padding-top:4px;border-top:1px solid rgba(100,116,139,0.3);font-size:8px;color:#64748b;text-align:center"><a href="/wevia-master.html" style="color:#06b6d4">Master</a> · <a href="/agents-archi.html" style="color:#06b6d4">Archi</a> · <a href="/wevia-meeting-rooms.html" style="color:#06b6d4">Rooms</a> · <a href="https://paperclip.weval-consulting.com" style="color:#06b6d4" target="_blank">Paperclip</a></div>';
body.innerHTML=html;
if(ts) ts.textContent=new Date().toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit',second:'2-digit'});
}catch(e){}
}
setTimeout(tick,1500);setInterval(tick,30000);
})();
</script>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,165 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL Security Scanner — Secret Detection</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#0a0e1a;--card:#111827;--border:#1e293b;--red:#ef4444;--green:#10b981;--yellow:#f59e0b;--blue:#3b82f6;--text:#e2e8f0;--muted:#64748b;--mono:'JetBrains Mono',monospace;--font:'DM Sans',sans-serif}
*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg);color:var(--text);font-family:var(--font)}
.top{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:rgba(17,24,39,.95);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}
.logo{font-size:18px;font-weight:700;color:var(--red)}.logo span{color:var(--text);font-weight:400}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;padding:20px 24px}
.kpi{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px;text-align:center}
.kpi .v{font-size:32px;font-weight:700;font-family:var(--mono)}.kpi .l{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:4px}
.main{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:0 24px 24px}
.full{grid-column:1/-1}.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;animation:fadeIn .3s}
.card h3{font-size:14px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.badge{font-size:10px;padding:2px 8px;border-radius:99px;font-weight:500}
.bg{background:rgba(16,185,129,.2);color:var(--green)}.br{background:rgba(239,68,68,.2);color:var(--red)}.by{background:rgba(245,158,11,.2);color:var(--yellow)}.bb{background:rgba(59,130,246,.2);color:var(--blue)}
.tool{display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid var(--border)}
.tool:last-child{border:none}.tool .dot{width:10px;height:10px;border-radius:50%}.tool .name{font-weight:600;font-size:13px}.tool .desc{font-size:11px;color:var(--muted)}
.finding{padding:10px 12px;border-left:3px solid var(--yellow);background:rgba(245,158,11,.05);margin-bottom:6px;border-radius:0 6px 6px 0;font-size:12px}
.key{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);font-size:12px}
.key .kn{font-weight:600;font-family:var(--mono)}.key .kv{color:var(--green);font-size:10px}
.btn{padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:700;font-size:13px;transition:.2s}
.btn:hover{transform:translateY(-1px)}
.btn-red{background:var(--red);color:white}.btn-green{background:var(--green);color:white}.btn-blue{background:var(--blue);color:white}
#status{font-family:var(--mono);font-size:12px;padding:4px 12px;border-radius:6px}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.scanning{animation:pulse 1s infinite}
@media(max-width:768px){.main{grid-template-columns:1fr}}
</style></head><body>
<div class="top">
<div class="logo">🔐 WEVAL <span>Security Scanner</span></div>
<div style="display:flex;gap:8px;align-items:center">
<span id="status" class="bg">● IDLE</span>
<button class="btn btn-red" onclick="runScan()">🔍 Scan Now</button>
<button class="btn btn-blue" onclick="syncKeys()">🔄 Sync Keys</button>
</div>
</div>
<div class="kpis" id="kpis"></div>
<div class="main">
<div class="card"><h3>🛠️ Scanner Tools <span class="badge bb" id="tools-count">5</span></h3><div id="tools-list"></div></div>
<div class="card"><h3>⚠️ Findings <span class="badge by" id="findings-count">0</span></h3><div id="findings-list"></div></div>
<div class="card"><h3>🔑 Tracked Keys <span class="badge bg" id="keys-count">0</span></h3><div id="keys-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card"><h3>📁 Sensitive Files <span class="badge br" id="files-count">0</span></h3><div id="files-list" style="max-height:400px;overflow-y:auto"></div></div>
<div class="card full"><h3>📋 Scan History</h3><div id="history" style="font-family:var(--mono);font-size:12px;color:var(--muted)">Loading...</div></div>
</div>
<script>
const API='/api/secret-scanner-api.php';
async function load(){
try{
const r=await fetch(API+'?action=results');
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
if(d.error){document.getElementById('history').textContent='No scan yet. Click Scan Now.';return}
// KPIs
const s=d.summary||{};
const kpis=[
{v:s.findings||0,l:'Findings',c:s.findings>5?'var(--red)':'var(--green)'},
{v:s.tools||5,l:'Tools Active',c:'var(--blue)'},
{v:(d.tools?.keyhacks?.tracked||0),l:'Keys Tracked',c:'var(--yellow)'},
{v:s.risk||'LOW',l:'Risk Level',c:s.risk==='HIGH'?'var(--red)':s.risk==='MEDIUM'?'var(--yellow)':'var(--green)'},
{v:d.repos||0,l:'Repos Scanned',c:'var(--blue)'},
{v:d.timestamp?.split('T')[1]?.substring(0,5)||'-',l:'Last Scan',c:'var(--muted)'}
];
document.getElementById('kpis').innerHTML=kpis.map(k=>'<div class="kpi"><div class="v" style="color:'+k.c+'">'+k.v+'</div><div class="l">'+k.l+'</div></div>').join('');
// Tools
const tools=[
{name:'TruffleHog',desc:'Git repo entropy + regex scanner',icon:'🐷',ok:d.tools?.trufflehog?.ok},
{name:'detect-secrets',desc:'Yelp secret detection engine',icon:'🔍',ok:d.tools?.['detect-secrets']?.ok!==false},
{name:'GitHub Dorking',desc:'Regex pattern search (AWS,Stripe,GitHub)',icon:'🕵️',ok:d.tools?.dorking?.ok},
{name:'KeyHacks',desc:'API key validation reference',icon:'🔑',ok:d.tools?.keyhacks?.ok},
{name:'shhgit Patterns',desc:'Sensitive file detection',icon:'🤫',ok:d.tools?.shhgit?.ok}
];
document.getElementById('tools-list').innerHTML=tools.map(t=>'<div class="tool"><div class="dot" style="background:'+(t.ok?'var(--green)':'var(--red)')+'"></div><div><div class="name">'+t.icon+' '+t.name+'</div><div class="desc">'+t.desc+'</div></div></div>').join('');
document.getElementById('tools-count').textContent=tools.filter(t=>t.ok).length+'/'+tools.length;
// Findings
const findings=d.findings||[];
document.getElementById('findings-count').textContent=findings.length;
document.getElementById('findings-list').innerHTML=findings.length?findings.map(f=>'<div class="finding"><strong>'+f.file+'</strong> — '+f.matches+' match(es)</div>').join(''):'<div style="color:var(--green);padding:20px;text-align:center">✅ No exposed secrets found</div>';
// Keys
const keys=d.tools?.keyhacks?.keys||[];
document.getElementById('keys-count').textContent=keys.length;
document.getElementById('keys-list').innerHTML=keys.map(k=>'<div class="key"><span class="kn">'+k+'</span><span class="kv">● tracked</span></div>').join('');
// Files
const files=d.tools?.shhgit?.files||[];
document.getElementById('files-count').textContent=files.length;
document.getElementById('files-list').innerHTML=files.map(f=>'<div style="padding:4px 8px;font-size:11px;font-family:var(--mono);border-bottom:1px solid var(--border)">📄 '+f+'</div>').join('')||'<div style="padding:20px;text-align:center;color:var(--muted)">No sensitive files outside secrets.env</div>';
// History
document.getElementById('history').textContent='Last scan: '+d.timestamp+' | Repos: '+d.repos+' | Risk: '+s.risk;
}catch(e){document.getElementById('history').textContent='Error: '+e.message}
}
async function runScan(){
document.getElementById('status').className='badge br scanning';
document.getElementById('status').textContent='● SCANNING...';
await fetch(API+'?action=scan');
setTimeout(()=>{document.getElementById('status').className='badge bg';document.getElementById('status').textContent='● DONE';load()},15000);
}
async function syncKeys(){
document.getElementById('status').textContent='● SYNCING...';
// Trigger key sync cron
await fetch(API+'?action=scan');
setTimeout(load,10000);
}
load();setInterval(load,60000);
</script>
<!-- WAVE 162 — Unified Pipeline Overlay -->
<div id="unifiedLiveOverlay" style="position:fixed;bottom:12px;right:12px;width:280px;max-height:calc(100vh - 120px);overflow-y:auto;background:linear-gradient(135deg,rgba(10,14,26,0.94),rgba(30,30,60,0.92));border:1px solid rgba(6,182,212,0.4);border-radius:10px;padding:10px;backdrop-filter:blur(14px);z-index:9999;font:600 9px Nunito,system-ui;color:#e2e8f0;box-shadow:0 4px 30px rgba(0,0,0,0.5)">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;padding-bottom:5px;border-bottom:1px solid rgba(100,116,139,0.3)">
<div style="font:900 10px Orbitron,system-ui;color:#06b6d4">🔴 <b id=closeLive style=cursor:pointer;margin-right:6px;color:gray onclick=unifiedLiveOverlay.remove()>x</b>UNIFIED LIVE</div>
<div id="ulo-ts" style="font-size:8px;color:#64748b"></div>
</div>
<div id="ulo-body">Loading...</div>
</div>
<script>
(function(){
const U='/api/weval-unified-pipeline.php';
async function tick(){
try{
const r=await fetch(U,{cache:'no-cache'});
if(!r.ok) return;
/* HTML_GUARD_V2_BATCH */ const _t_d=await r.text(); let d=null; {var _q=(_t_d||"").trim();if(_q.startsWith("<!DOCTYPE")||_q.startsWith("<html")){d={error:"[HTTP "+(r.status||"?")+"] Backend indisponible",isHtmlError:true};}else{try{d=JSON.parse(_q)}catch(e){d={error:"[JSON] "+e.message}}}}
const body=document.getElementById('ulo-body');
const ts=document.getElementById('ulo-ts');
if(!body) return;
const h=d.l99.health||'?';
const hc={GREEN:'#10b981',YELLOW:'#f59e0b',RED:'#ef4444'}[h]||'#64748b';
let html='<div style="background:'+hc+'15;border-left:3px solid '+hc+';padding:5px;margin-bottom:5px;border-radius:3px"><b style="color:'+hc+'">● '+h+'</b> L99 <b>'+d.l99.pass+'/'+d.l99.total+'</b><br><span style="color:#94a3b8">Disk '+d.system.disk_pct+'% Docker '+d.system.docker_count+' Crons '+d.system.cron_count+'</span></div>';
html+='<div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:5px"><div style="background:rgba(6,182,212,0.1);border:1px solid rgba(6,182,212,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#06b6d4">SOVEREIGN</div><b>'+d.providers.count+'</b> providers<br><b>'+d.ollama.models+'</b> Ollama<br><b>'+d.qdrant.collections.length+'</b> Qdrant</div><div style="background:rgba(139,92,246,0.1);border:1px solid rgba(139,92,246,0.3);border-radius:4px;padding:4px"><div style="font:800 8px Orbitron;color:#8b5cf6">PAPERCLIP</div><b>'+d.goals.length+'</b> goals<br><b>'+d.projects.length+'</b> projects<br><b>'+d.routines.length+'</b> routines</div></div>';
html+='<div style="background:rgba(245,158,11,0.1);border:1px solid rgba(245,158,11,0.3);border-radius:4px;padding:4px;margin-bottom:5px"><div style="font:800 8px Orbitron;color:#f59e0b">ETHICA</div><b>'+(d.ethica.hcps_validated/1000).toFixed(0)+'K</b> HCPs '+d.ethica.coverage.join(' ')+'</div>';
const rpa=d.routines_per_agent||{};
const top=Object.entries(rpa).sort((a,b)=>b[1]-a[1]).slice(0,5);
if(top.length){
html+='<div style="font:800 8px Orbitron;color:#10b981;margin:4px 0">TOP AGENTS</div>';
top.forEach(([n,c])=>{html+='<div style="display:flex;justify-content:space-between;padding:1px 3px;background:rgba(16,185,129,0.05);border-radius:2px;margin-bottom:1px"><span>'+n+'</span><b style="color:#10b981">'+c+'</b></div>';});
}
html+='<div style="margin-top:5px;padding-top:4px;border-top:1px solid rgba(100,116,139,0.3);font-size:8px;color:#64748b;text-align:center"><a href="/wevia-master.html" style="color:#06b6d4">Master</a> · <a href="/agents-archi.html" style="color:#06b6d4">Archi</a> · <a href="/wevia-meeting-rooms.html" style="color:#06b6d4">Rooms</a> · <a href="https://paperclip.weval-consulting.com" style="color:#06b6d4" target="_blank">Paperclip</a></div>';
body.innerHTML=html;
if(ts) ts.textContent=new Date().toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit',second:'2-digit'});
}catch(e){}
}
setTimeout(tick,1500);setInterval(tick,30000);
})();
</script>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Security Hub — WEVAL</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{background:#0a0e1a;color:#e2e8f0;font-family:'Segoe UI',system-ui,sans-serif;min-height:100vh}
.top{background:linear-gradient(135deg,#0f172a,#1a1040,#1e293b);padding:32px 40px;border-bottom:1px solid rgba(99,102,241,.2)}
.top h1{font-size:32px;font-weight:800;color:#fff}.top h1 span{background:linear-gradient(135deg,#818cf8,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.top p{color:#94a3b8;margin-top:6px;font-size:15px}
.nav{display:flex;gap:10px;margin-top:16px;flex-wrap:wrap}.nav a{color:#a5b4fc;text-decoration:none;padding:6px 16px;border:1px solid rgba(99,102,241,.3);border-radius:20px;font-size:13px;transition:.2s}.nav a:hover{background:rgba(99,102,241,.15);color:#fff}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;padding:24px 40px}
.card{background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.15);border-radius:14px;padding:18px;text-decoration:none;display:block;transition:.2s}.card:hover{border-color:#6366f1;transform:translateY(-2px)}
.card h3{font-size:16px;font-weight:700;color:#818cf8;margin-bottom:6px}.card p{font-size:13px;color:#94a3b8}
.badge{display:inline-block;margin-top:8px;font-size:11px;padding:3px 10px;border-radius:8px}
.int{background:rgba(16,185,129,.15);color:#10b981}.ext{background:rgba(99,102,241,.15);color:#818cf8}
.section{padding:24px 40px}.section h2{font-size:20px;font-weight:700;margin-bottom:16px}
</style></head><body>
<!-- MEGA-NAV -->
<div style="background:rgba(99,102,241,.04);border-bottom:1px solid rgba(99,102,241,.1);padding:8px 40px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<span style="color:#64748b;font-size:11px;font-weight:600;letter-spacing:1px">HUBS</span>
<a href="/wevia-hub.html" style="color:#10b981;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(16,185,129,.2);border-radius:12px">🧠 WEVIA</a>
<a href="/ai-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🤖 AI</a>
<a href="/agents-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👥 Agents</a>
<a href="/monitoring-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Monitor</a>
<a href="/email-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 Email</a>
<a href="/office-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Office</a>
<a href="/ethica-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👨‍⚕️ Ethica</a>
<a href="/wevads-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 WEVADS</a>
<a href="/blade-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ Blade</a>
<a href="/security-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🛡️ Sécu</a>
<a href="/gpu-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ GPU</a>
<a href="/keys-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔐 Keys</a>
<a href="/cloudflare-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">☁️ CF</a>
<a href="/google-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔍 Google</a>
<a href="/namecheap-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🌐 NC</a>
<a href="/tools-hub.html" style="color:#f59e0b;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(245,158,11,.2);border-radius:12px;font-weight:700">⭐ ALL</a>
</div>
<div class="top"><h1>🛡️ <span>Security Hub</span></h1><p>Sécurité souveraine — CrowdSec, WAF, SSL, audit, conformité</p>
<div class="nav"><a href="/keys-hub.html">Keys</a><a href="/monitoring-hub.html">Monitoring</a><a href="/tools-hub.html">Tools</a></div></div>
<div class="section"><h2 style="color:#10b981">🛡️ SÉCURITÉ</h2></div>
<div class="grid"><a href="/security-dashboard.html" class="card"><h3>📊 Security Dashboard</h3><p>CrowdSec, WAF, rate limiting</p><span class="badge int">INTERNE</span></a>
<a href="/trust-center.html" class="card"><h3>🔐 Trust Center</h3><p>Audit sécurité, conformité, RGPD</p><span class="badge int">INTERNE</span></a>
<a href="/vault" class="card"><h3>🔑 Vaultwarden</h3><p>Coffre-fort mots de passe</p><span class="badge int">INTERNE</span></a>
<a href="/sessions-monitor.html" class="card"><h3>📋 Sessions Monitor</h3><p>Sessions actives, tokens</p><span class="badge int">INTERNE</span></a>
<a href="/cyber-monitor.html" class="card"><h3>🛡️ Cyber Monitor</h3><p>Alertes intrusions</p><span class="badge int">INTERNE</span></a>
</div>
<div class="section"><h2 style="color:#818cf8">📊 CONFORMITÉ</h2></div>
<div class="grid"><a href="/cgu.html" class="card"><h3>📋 CGU</h3><p>Conditions générales</p><span class="badge int">INTERNE</span></a>
<a href="/privacy-policy.html" class="card"><h3>🔒 Privacy Policy</h3><p>Politique confidentialité</p><span class="badge int">INTERNE</span></a>
<a href="/terms-of-service.html" class="card"><h3>📄 Terms</h3><p>Conditions de service</p><span class="badge int">INTERNE</span></a>
<a href="/sovereign-monitor.html" class="card"><h3>⚡ Sovereign Monitor</h3><p>Monitoring souveraineté</p><span class="badge int">INTERNE</span></a>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Security Hub — WEVAL</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{background:#0a0e1a;color:#e2e8f0;font-family:'Segoe UI',system-ui,sans-serif;min-height:100vh}
.top{background:linear-gradient(135deg,#0f172a,#1a1040,#1e293b);padding:32px 40px;border-bottom:1px solid rgba(99,102,241,.2)}
.top h1{font-size:32px;font-weight:800;color:#fff}.top h1 span{background:linear-gradient(135deg,#818cf8,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.top p{color:#94a3b8;margin-top:6px;font-size:15px}
.nav{display:flex;gap:10px;margin-top:16px;flex-wrap:wrap}.nav a{color:#a5b4fc;text-decoration:none;padding:6px 16px;border:1px solid rgba(99,102,241,.3);border-radius:20px;font-size:13px;transition:.2s}.nav a:hover{background:rgba(99,102,241,.15);color:#fff}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;padding:24px 40px}
.card{background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.15);border-radius:14px;padding:18px;text-decoration:none;display:block;transition:.2s}.card:hover{border-color:#6366f1;transform:translateY(-2px)}
.card h3{font-size:16px;font-weight:700;color:#818cf8;margin-bottom:6px}.card p{font-size:13px;color:#94a3b8}
.badge{display:inline-block;margin-top:8px;font-size:11px;padding:3px 10px;border-radius:8px}
.int{background:rgba(16,185,129,.15);color:#10b981}.ext{background:rgba(99,102,241,.15);color:#818cf8}
.section{padding:24px 40px}.section h2{font-size:20px;font-weight:700;margin-bottom:16px}
</style></head><body>
<!-- MEGA-NAV -->
<div style="background:rgba(99,102,241,.04);border-bottom:1px solid rgba(99,102,241,.1);padding:8px 40px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<span style="color:#64748b;font-size:11px;font-weight:600;letter-spacing:1px">HUBS</span>
<a href="/wevia-hub.html" style="color:#10b981;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(16,185,129,.2);border-radius:12px">🧠 WEVIA</a>
<a href="/ai-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🤖 AI</a>
<a href="/agents-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👥 Agents</a>
<a href="/monitoring-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Monitor</a>
<a href="/email-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 Email</a>
<a href="/office-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Office</a>
<a href="/ethica-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👨‍⚕️ Ethica</a>
<a href="/wevads-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 WEVADS</a>
<a href="/blade-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ Blade</a>
<a href="/security-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🛡️ Sécu</a>
<a href="/gpu-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ GPU</a>
<a href="/keys-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔐 Keys</a>
<a href="/cloudflare-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">☁️ CF</a>
<a href="/google-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔍 Google</a>
<a href="/namecheap-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🌐 NC</a>
<a href="/tools-hub.html" style="color:#f59e0b;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(245,158,11,.2);border-radius:12px;font-weight:700">⭐ ALL</a>
</div>
<div class="top"><h1>🛡️ <span>Security Hub</span></h1><p>Sécurité souveraine — CrowdSec, WAF, SSL, audit, conformité</p>
<div class="nav"><a href="/keys-hub.html">Keys</a><a href="/monitoring-hub.html">Monitoring</a><a href="/tools-hub.html">Tools</a></div></div>
<div class="section"><h2 style="color:#10b981">🛡️ SÉCURITÉ</h2></div>
<div class="grid"><a href="/security-dashboard.html" class="card"><h3>📊 Security Dashboard</h3><p>CrowdSec, WAF, rate limiting</p><span class="badge int">INTERNE</span></a>
<a href="/trust-center.html" class="card"><h3>🔐 Trust Center</h3><p>Audit sécurité, conformité, RGPD</p><span class="badge int">INTERNE</span></a>
<a href="/vault" class="card"><h3>🔑 Vaultwarden</h3><p>Coffre-fort mots de passe</p><span class="badge int">INTERNE</span></a>
<a href="/sessions-monitor.html" class="card"><h3>📋 Sessions Monitor</h3><p>Sessions actives, tokens</p><span class="badge int">INTERNE</span></a>
<a href="/cyber-monitor.html" class="card"><h3>🛡️ Cyber Monitor</h3><p>Alertes intrusions</p><span class="badge int">INTERNE</span></a>
</div>
<div class="section"><h2 style="color:#818cf8">📊 CONFORMITÉ</h2></div>
<div class="grid"><a href="/cgu.html" class="card"><h3>📋 CGU</h3><p>Conditions générales</p><span class="badge int">INTERNE</span></a>
<a href="/privacy-policy.html" class="card"><h3>🔒 Privacy Policy</h3><p>Politique confidentialité</p><span class="badge int">INTERNE</span></a>
<a href="/terms-of-service.html" class="card"><h3>📄 Terms</h3><p>Conditions de service</p><span class="badge int">INTERNE</span></a>
<a href="/sovereign-monitor.html" class="card"><h3>⚡ Sovereign Monitor</h3><p>Monitoring souveraineté</p><span class="badge int">INTERNE</span></a>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Security Hub — WEVAL</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{background:#0a0e1a;color:#e2e8f0;font-family:'Segoe UI',system-ui,sans-serif;min-height:100vh}
.top{background:linear-gradient(135deg,#0f172a,#1a1040,#1e293b);padding:32px 40px;border-bottom:1px solid rgba(99,102,241,.2)}
.top h1{font-size:32px;font-weight:800;color:#fff}.top h1 span{background:linear-gradient(135deg,#818cf8,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.top p{color:#94a3b8;margin-top:6px;font-size:15px}
.nav{display:flex;gap:10px;margin-top:16px;flex-wrap:wrap}.nav a{color:#a5b4fc;text-decoration:none;padding:6px 16px;border:1px solid rgba(99,102,241,.3);border-radius:20px;font-size:13px;transition:.2s}.nav a:hover{background:rgba(99,102,241,.15);color:#fff}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;padding:24px 40px}
.card{background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.15);border-radius:14px;padding:18px;text-decoration:none;display:block;transition:.2s}.card:hover{border-color:#6366f1;transform:translateY(-2px)}
.card h3{font-size:16px;font-weight:700;color:#818cf8;margin-bottom:6px}.card p{font-size:13px;color:#94a3b8}
.badge{display:inline-block;margin-top:8px;font-size:11px;padding:3px 10px;border-radius:8px}
.int{background:rgba(16,185,129,.15);color:#10b981}.ext{background:rgba(99,102,241,.15);color:#818cf8}
.section{padding:24px 40px}.section h2{font-size:20px;font-weight:700;margin-bottom:16px}
</style></head><body>
<!-- MEGA-NAV -->
<div style="background:rgba(99,102,241,.04);border-bottom:1px solid rgba(99,102,241,.1);padding:8px 40px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<span style="color:#64748b;font-size:11px;font-weight:600;letter-spacing:1px">HUBS</span>
<a href="/wevia-hub.html" style="color:#10b981;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(16,185,129,.2);border-radius:12px">🧠 WEVIA</a>
<a href="/ai-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🤖 AI</a>
<a href="/agents-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👥 Agents</a>
<a href="/monitoring-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Monitor</a>
<a href="/email-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 Email</a>
<a href="/office-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Office</a>
<a href="/ethica-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👨‍⚕️ Ethica</a>
<a href="/wevads-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 WEVADS</a>
<a href="/blade-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ Blade</a>
<a href="/security-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🛡️ Sécu</a>
<a href="/gpu-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ GPU</a>
<a href="/keys-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔐 Keys</a>
<a href="/cloudflare-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">☁️ CF</a>
<a href="/google-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔍 Google</a>
<a href="/namecheap-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🌐 NC</a>
<a href="/tools-hub.html" style="color:#f59e0b;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(245,158,11,.2);border-radius:12px;font-weight:700">⭐ ALL</a>
</div>
<div class="top"><h1>🛡️ <span>Security Hub</span></h1><p>Sécurité souveraine — CrowdSec, WAF, SSL, audit, conformité</p>
<div class="nav"><a href="/keys-hub.html">Keys</a><a href="/monitoring-hub.html">Monitoring</a><a href="/tools-hub.html">Tools</a></div></div>
<div class="section"><h2 style="color:#10b981">🛡️ SÉCURITÉ</h2></div>
<div class="grid"><a href="/security-dashboard.html" class="card"><h3>📊 Security Dashboard</h3><p>CrowdSec, WAF, rate limiting</p><span class="badge int">INTERNE</span></a>
<a href="/trust-center.html" class="card"><h3>🔐 Trust Center</h3><p>Audit sécurité, conformité, RGPD</p><span class="badge int">INTERNE</span></a>
<a href="/vault" class="card"><h3>🔑 Vaultwarden</h3><p>Coffre-fort mots de passe</p><span class="badge int">INTERNE</span></a>
<a href="/sessions-monitor.html" class="card"><h3>📋 Sessions Monitor</h3><p>Sessions actives, tokens</p><span class="badge int">INTERNE</span></a>
<a href="/cyber-monitor.html" class="card"><h3>🛡️ Cyber Monitor</h3><p>Alertes intrusions</p><span class="badge int">INTERNE</span></a>
</div>
<div class="section"><h2 style="color:#818cf8">📊 CONFORMITÉ</h2></div>
<div class="grid"><a href="/cgu.html" class="card"><h3>📋 CGU</h3><p>Conditions générales</p><span class="badge int">INTERNE</span></a>
<a href="/privacy-policy.html" class="card"><h3>🔒 Privacy Policy</h3><p>Politique confidentialité</p><span class="badge int">INTERNE</span></a>
<a href="/terms-of-service.html" class="card"><h3>📄 Terms</h3><p>Conditions de service</p><span class="badge int">INTERNE</span></a>
<a href="/sovereign-monitor.html" class="card"><h3>⚡ Sovereign Monitor</h3><p>Monitoring souveraineté</p><span class="badge int">INTERNE</span></a>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Security Hub — WEVAL</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{background:#0a0e1a;color:#e2e8f0;font-family:'Segoe UI',system-ui,sans-serif;min-height:100vh}
.top{background:linear-gradient(135deg,#0f172a,#1a1040,#1e293b);padding:32px 40px;border-bottom:1px solid rgba(99,102,241,.2)}
.top h1{font-size:32px;font-weight:800;color:#fff}.top h1 span{background:linear-gradient(135deg,#818cf8,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.top p{color:#94a3b8;margin-top:6px;font-size:15px}
.nav{display:flex;gap:10px;margin-top:16px;flex-wrap:wrap}.nav a{color:#a5b4fc;text-decoration:none;padding:6px 16px;border:1px solid rgba(99,102,241,.3);border-radius:20px;font-size:13px;transition:.2s}.nav a:hover{background:rgba(99,102,241,.15);color:#fff}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;padding:24px 40px}
.card{background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.15);border-radius:14px;padding:18px;text-decoration:none;display:block;transition:.2s}.card:hover{border-color:#6366f1;transform:translateY(-2px)}
.card h3{font-size:16px;font-weight:700;color:#818cf8;margin-bottom:6px}.card p{font-size:13px;color:#94a3b8}
.badge{display:inline-block;margin-top:8px;font-size:11px;padding:3px 10px;border-radius:8px}
.int{background:rgba(16,185,129,.15);color:#10b981}.ext{background:rgba(99,102,241,.15);color:#818cf8}
.section{padding:24px 40px}.section h2{font-size:20px;font-weight:700;margin-bottom:16px}
</style></head><body>
<!-- MEGA-NAV -->
<div style="background:rgba(99,102,241,.04);border-bottom:1px solid rgba(99,102,241,.1);padding:8px 40px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<span style="color:#64748b;font-size:11px;font-weight:600;letter-spacing:1px">HUBS</span>
<a href="/wevia-hub.html" style="color:#10b981;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(16,185,129,.2);border-radius:12px">🧠 WEVIA</a>
<a href="/ai-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🤖 AI</a>
<a href="/agents-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👥 Agents</a>
<a href="/monitoring-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Monitor</a>
<a href="/email-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 Email</a>
<a href="/office-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Office</a>
<a href="/ethica-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👨‍⚕️ Ethica</a>
<a href="/wevads-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 WEVADS</a>
<a href="/blade-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ Blade</a>
<a href="/security-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🛡️ Sécu</a>
<a href="/gpu-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ GPU</a>
<a href="/keys-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔐 Keys</a>
<a href="/cloudflare-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">☁️ CF</a>
<a href="/google-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔍 Google</a>
<a href="/namecheap-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🌐 NC</a>
<a href="/tools-hub.html" style="color:#f59e0b;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(245,158,11,.2);border-radius:12px;font-weight:700">⭐ ALL</a>
</div>
<div class="top"><h1>🛡️ <span>Security Hub</span></h1><p>Sécurité souveraine — CrowdSec, WAF, SSL, audit, conformité</p>
<div class="nav"><a href="/keys-hub.html">Keys</a><a href="/monitoring-hub.html">Monitoring</a><a href="/tools-hub.html">Tools</a></div></div>
<div class="section"><h2 style="color:#10b981">🛡️ SÉCURITÉ</h2></div>
<div class="grid"><a href="/security-dashboard.html" class="card"><h3>📊 Security Dashboard</h3><p>CrowdSec, WAF, rate limiting</p><span class="badge int">INTERNE</span></a>
<a href="/trust-center.html" class="card"><h3>🔐 Trust Center</h3><p>Audit sécurité, conformité, RGPD</p><span class="badge int">INTERNE</span></a>
<a href="/vault" class="card"><h3>🔑 Vaultwarden</h3><p>Coffre-fort mots de passe</p><span class="badge int">INTERNE</span></a>
<a href="/sessions-monitor.html" class="card"><h3>📋 Sessions Monitor</h3><p>Sessions actives, tokens</p><span class="badge int">INTERNE</span></a>
<a href="/cyber-monitor.html" class="card"><h3>🛡️ Cyber Monitor</h3><p>Alertes intrusions</p><span class="badge int">INTERNE</span></a>
</div>
<div class="section"><h2 style="color:#818cf8">📊 CONFORMITÉ</h2></div>
<div class="grid"><a href="/cgu.html" class="card"><h3>📋 CGU</h3><p>Conditions générales</p><span class="badge int">INTERNE</span></a>
<a href="/privacy-policy.html" class="card"><h3>🔒 Privacy Policy</h3><p>Politique confidentialité</p><span class="badge int">INTERNE</span></a>
<a href="/terms-of-service.html" class="card"><h3>📄 Terms</h3><p>Conditions de service</p><span class="badge int">INTERNE</span></a>
<a href="/sovereign-monitor.html" class="card"><h3>⚡ Sovereign Monitor</h3><p>Monitoring souveraineté</p><span class="badge int">INTERNE</span></a>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Security Hub — WEVAL</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{background:#0a0e1a;color:#e2e8f0;font-family:'Segoe UI',system-ui,sans-serif;min-height:100vh}
.top{background:linear-gradient(135deg,#0f172a,#1a1040,#1e293b);padding:32px 40px;border-bottom:1px solid rgba(99,102,241,.2)}
.top h1{font-size:32px;font-weight:800;color:#fff}.top h1 span{background:linear-gradient(135deg,#818cf8,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.top p{color:#94a3b8;margin-top:6px;font-size:15px}
.nav{display:flex;gap:10px;margin-top:16px;flex-wrap:wrap}.nav a{color:#a5b4fc;text-decoration:none;padding:6px 16px;border:1px solid rgba(99,102,241,.3);border-radius:20px;font-size:13px;transition:.2s}.nav a:hover{background:rgba(99,102,241,.15);color:#fff}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;padding:24px 40px}
.card{background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.15);border-radius:14px;padding:18px;text-decoration:none;display:block;transition:.2s}.card:hover{border-color:#6366f1;transform:translateY(-2px)}
.card h3{font-size:16px;font-weight:700;color:#818cf8;margin-bottom:6px}.card p{font-size:13px;color:#94a3b8}
.badge{display:inline-block;margin-top:8px;font-size:11px;padding:3px 10px;border-radius:8px}
.int{background:rgba(16,185,129,.15);color:#10b981}.ext{background:rgba(99,102,241,.15);color:#818cf8}
.section{padding:24px 40px}.section h2{font-size:20px;font-weight:700;margin-bottom:16px}
</style></head><body>
<!-- MEGA-NAV -->
<div style="background:rgba(99,102,241,.04);border-bottom:1px solid rgba(99,102,241,.1);padding:8px 40px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<span style="color:#64748b;font-size:11px;font-weight:600;letter-spacing:1px">HUBS</span>
<a href="/wevia-hub.html" style="color:#10b981;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(16,185,129,.2);border-radius:12px">🧠 WEVIA</a>
<a href="/ai-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🤖 AI</a>
<a href="/agents-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👥 Agents</a>
<a href="/monitoring-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Monitor</a>
<a href="/email-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 Email</a>
<a href="/office-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📊 Office</a>
<a href="/ethica-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">👨‍⚕️ Ethica</a>
<a href="/wevads-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">📧 WEVADS</a>
<a href="/blade-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ Blade</a>
<a href="/security-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🛡️ Sécu</a>
<a href="/gpu-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">⚡ GPU</a>
<a href="/keys-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔐 Keys</a>
<a href="/cloudflare-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">☁️ CF</a>
<a href="/google-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🔍 Google</a>
<a href="/namecheap-hub.html" style="color:#818cf8;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(99,102,241,.2);border-radius:12px">🌐 NC</a>
<a href="/tools-hub.html" style="color:#f59e0b;text-decoration:none;font-size:12px;padding:3px 10px;border:1px solid rgba(245,158,11,.2);border-radius:12px;font-weight:700">⭐ ALL</a>
</div>
<div class="top"><h1>🛡️ <span>Security Hub</span></h1><p>Sécurité souveraine — CrowdSec, WAF, SSL, audit, conformité</p>
<div class="nav"><a href="/keys-hub.html">Keys</a><a href="/monitoring-hub.html">Monitoring</a><a href="/tools-hub.html">Tools</a></div></div>
<div class="section"><h2 style="color:#10b981">🛡️ SÉCURITÉ</h2></div>
<div class="grid"><a href="/security-dashboard.html" class="card"><h3>📊 Security Dashboard</h3><p>CrowdSec, WAF, rate limiting</p><span class="badge int">INTERNE</span></a>
<a href="/trust-center.html" class="card"><h3>🔐 Trust Center</h3><p>Audit sécurité, conformité, RGPD</p><span class="badge int">INTERNE</span></a>
<a href="/vault" class="card"><h3>🔑 Vaultwarden</h3><p>Coffre-fort mots de passe</p><span class="badge int">INTERNE</span></a>
<a href="/sessions-monitor.html" class="card"><h3>📋 Sessions Monitor</h3><p>Sessions actives, tokens</p><span class="badge int">INTERNE</span></a>
<a href="/cyber-monitor.html" class="card"><h3>🛡️ Cyber Monitor</h3><p>Alertes intrusions</p><span class="badge int">INTERNE</span></a>
</div>
<div class="section"><h2 style="color:#818cf8">📊 CONFORMITÉ</h2></div>
<div class="grid"><a href="/cgu.html" class="card"><h3>📋 CGU</h3><p>Conditions générales</p><span class="badge int">INTERNE</span></a>
<a href="/privacy-policy.html" class="card"><h3>🔒 Privacy Policy</h3><p>Politique confidentialité</p><span class="badge int">INTERNE</span></a>
<a href="/terms-of-service.html" class="card"><h3>📄 Terms</h3><p>Conditions de service</p><span class="badge int">INTERNE</span></a>
<a href="/sovereign-monitor.html" class="card"><h3>⚡ Sovereign Monitor</h3><p>Monitoring souveraineté</p><span class="badge int">INTERNE</span></a>
</div>
<!-- NL-AutoWire-badge-v1 -->
<a href="/nl-autowire-status.html" id="nlAutowireBadge" style="position:fixed;bottom:8px;right:8px;background:#1a3d2c;color:#56d364;padding:4px 10px;border-radius:12px;font-size:0.78em;font-family:-apple-system,sans-serif;text-decoration:none;z-index:99999;border:1px solid rgba(86,211,100,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.3);">NL-AutoWire &check;</a>
<!-- CARTO_REMOVED -->
<!-- CARTO_BANNER_V1 -->
<div style="position:fixed;bottom:20px;right:20px;z-index:9999;background:linear-gradient(135deg,#141931,#2d1b5e);border:1px solid #64ffda;border-radius:12px;padding:12px 18px;box-shadow:0 4px 20px rgba(100,255,218,.3);font-family:-apple-system,Segoe UI,sans-serif;font-size:13px">
<a href="/cartographie-screens.html" style="color:#64ffda;text-decoration:none;font-weight:600;display:flex;align-items:center;gap:8px" title="Cartographie exhaustive de tous les ecrans live">
<span style="font-size:18px">&#128506;</span> Cartographie live
<span id="carto-banner-count" style="color:#8892b0;font-size:11px">3914 ecrans</span>
</a>
</div>
<script>
(function(){
fetch('/api/screens-health.php?_='+Date.now(),{cache:'no-store'}).then(r=>r.json()).then(d=>{
const c=d.counts||{}; const up=c.UP||0; const slow=c.SLOW||0; const br=c.BROKEN||0;
const el=document.getElementById('carto-banner-count');
if(el) el.innerHTML=`<span style="color:#22c55e">${up} UP</span> / <span style="color:#f59e0b">${slow} Lent</span> / <span style="color:#ef4444">${br} 5xx</span>`;
}).catch(()=>{});
})();
</script>
<!-- /CARTO_BANNER_V1 -->
</body></html>

View File

@@ -1,5 +1,5 @@
{ {
"timestamp": "2026-04-17T01:05:01.915624", "timestamp": "2026-04-17T01:20:01.755029",
"layers": { "layers": {
"DOCKER": { "DOCKER": {
"pass": 19, "pass": 19,

File diff suppressed because one or more lines are too long

View File

@@ -114,6 +114,10 @@ def regen_carto(screens):
_existing = __import__("json").loads(_m.group(1)) _existing = __import__("json").loads(_m.group(1))
_existing_urls = {e["url"] for e in _existing} _existing_urls = {e["url"] for e in _existing}
_new_only = [s for s in screens if s["url"] not in _existing_urls] _new_only = [s for s in screens if s["url"] not in _existing_urls]
# NEVER_SHRINK_GUARD
if len(screens) < len(_existing) * 0.9:
print("GUARD: scan=%d < existing=%d*0.9 - REFUSING" % (len(screens), len(_existing)))
return False
if not _new_only: if not _new_only:
print(f"No new screens (existing={len(_existing)})") print(f"No new screens (existing={len(_existing)})")
return False return False

View File

@@ -1 +1 @@
{"title":"cartographie-screens","url":"https://weval-consulting.com/cartographie-screens.html","total":1618,"sources":{"S95-Arsenal":1378,"S95-WEVADS":52,"S204":179,"S204-PHP":7},"updated":"2026-04-17T00:54:28+02:00"} {"title":"cartographie-screens","url":"https://weval-consulting.com/cartographie-screens.html","total":1618,"sources":{"S95-Arsenal":1378,"S95-WEVADS":52,"S204":179,"S204-PHP":7},"updated":"2026-04-17T01:11:37+02:00"}