Files
html/value-stream-mapping.html
2026-04-19 22:40:02 +02:00

394 lines
29 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL — Value Stream Mapping</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800;900&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
:root{--bg:#0f1117;--card:#1a1d27;--border:#2a2d3a;--text:#e2e4eb;--dim:#6b7280;--accent:#3b82f6;--green:#10b981;--orange:#f59e0b;--red:#ef4444;--purple:#8b5cf6;--cyan:#06b6d4;--pink:#ec4899}
body{background:var(--bg);color:var(--text);font-family:'DM Sans',sans-serif;min-height:100vh}
.header{background:linear-gradient(135deg,#1a1d27 0%,#0f1117 100%);border-bottom:1px solid var(--border);padding:16px 24px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}
.header h1{font-family:'JetBrains Mono',monospace;font-size:18px;font-weight:700;background:linear-gradient(135deg,#3b82f6,#8b5cf6);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.header .live{font-size:11px;color:var(--green);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.tabs{display:flex;gap:2px;background:var(--card);border-radius:8px;padding:3px;border:1px solid var(--border)}
.tab{padding:6px 14px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;color:var(--dim);transition:.2s}
.tab:hover{color:var(--text)}
.tab.active{background:var(--accent);color:#fff}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:10px;padding:16px 24px}
.kpi{background:var(--card);border:1px solid var(--border);border-radius:10px;padding:12px;text-align:center}
.kpi .val{font-family:'JetBrains Mono',monospace;font-size:22px;font-weight:700}
.kpi .lbl{font-size:10px;color:var(--dim);margin-top:2px;text-transform:uppercase;letter-spacing:1px}
.kpi.green .val{color:var(--green)}.kpi.blue .val{color:var(--accent)}.kpi.orange .val{color:var(--orange)}.kpi.purple .val{color:var(--purple)}.kpi.cyan .val{color:var(--cyan)}.kpi.pink .val{color:var(--pink)}.kpi.red .val{color:var(--red)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(420px,1fr));gap:12px;padding:0 24px 24px}
.dept{background:var(--card);border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:.2s}
.dept:hover{border-color:var(--accent);transform:translateY(-1px)}
.dept-head{padding:12px 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border)}
.dept-head h3{font-size:14px;font-weight:700;display:flex;align-items:center;gap:8px}
.dept-head .badge{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:600}
.dept-head .cnt{font-size:11px;color:var(--dim)}
.dept-body{padding:12px 16px;display:flex;flex-wrap:wrap;gap:6px}
.agent{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;border:1px solid transparent;transition:.15s;cursor:default}
.agent:hover{transform:scale(1.05);border-color:rgba(255,255,255,.1)}
.agent .icon{font-size:13px}
.pipeline{padding:8px 16px;border-top:1px solid var(--border);display:flex;align-items:center;gap:8px;overflow-x:auto}
.pipe-step{font-size:10px;padding:3px 8px;border-radius:4px;background:rgba(59,130,246,.1);color:var(--accent);font-weight:600;white-space:nowrap}
.pipe-arrow{color:var(--dim);font-size:10px}
.output{padding:8px 16px;border-top:1px solid var(--border);font-size:11px;color:var(--dim);display:flex;align-items:center;gap:6px}
.output .metric{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:13px}
.section-title{padding:20px 24px 8px;font-size:13px;font-weight:700;color:var(--dim);text-transform:uppercase;letter-spacing:2px;display:flex;align-items:center;gap:8px}
.section-title::after{content:'';flex:1;height:1px;background:var(--border)}
.n8n-tag{font-size:9px;padding:1px 5px;border-radius:3px;background:rgba(59,130,246,.2);color:var(--accent);font-weight:700;margin-left:4px}
.status-dot{width:6px;height:6px;border-radius:50%;display:inline-block}
.status-dot.green{background:var(--green)}.status-dot.orange{background:var(--orange)}.status-dot.red{background:var(--red)}
#view-agents,#view-n8n,#view-infra{display:none}
#view-overview{display:block}
</style>
</head>
<body style="padding-top:60px"><div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
<div style="position:fixed;top:30px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:4px;z-index:100;background:#f8fafcee;backdrop-filter:blur(8px);font-family:Nunito,sans-serif">
<a href="/agents-archi.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Architecture</a>
<a href="/director-center.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Director</a>
<a href="/wevia-meeting-rooms.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Rooms</a>
<a href="/enterprise-model.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Enterprise</a>
<a href="/agents-ia.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Pyramid</a>
<a href="/director-chat.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Chat</a>
<a href="/l99-brain.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">L99</a>
</div>
<div class="header">
<h1>⚡ WEVAL Value Stream Mapping</h1>
<div style="display:flex;align-items:center;gap:16px">
<div class="tabs" id="tabs">
<div class="tab active" onclick="showView('overview')">Overview</div>
<div class="tab" onclick="showView('agents')">Agents</div>
<div class="tab" onclick="showView('n8n')">n8n Workflows</div>
<div class="tab" onclick="showView('infra')">Infrastructure</div>
</div>
<span class="live">● LIVE</span>
</div>
</div>
<div class="kpis">
<div class="kpi blue"><div class="val">191</div><div class="lbl">Agents</div></div>
<div class="kpi purple"><div class="val">21</div><div class="lbl">Depts</div></div>
<div class="kpi cyan"><div class="val">15</div><div class="lbl">n8n Flows</div></div>
<div class="kpi green"><div class="val">685</div><div class="lbl">OSS Tools</div></div>
<div class="kpi orange"><div class="val">3M</div><div class="lbl">Contacts</div></div>
<div class="kpi pink"><div class="val">141K+</div><div class="lbl">HCPs</div></div>
<div class="kpi blue"><div class="val">20</div><div class="lbl">Docker</div></div>
<div class="kpi green"><div class="val">94%</div><div class="lbl">L99 Score</div></div>
</div>
<div id="view-overview">
<div class="section-title">🏢 Departments & Pipelines</div>
<div class="grid" id="dept-grid"></div>
</div>
<div id="view-agents">
<div class="section-title">🤖 All Agents by Department</div>
<div class="grid" id="agent-grid"></div>
</div>
<div id="view-n8n">
<div class="section-title">⚙ n8n Workflows (15)</div>
<div class="grid" id="n8n-grid"></div>
</div>
<div id="view-infra">
<div class="section-title">🏗️ Infrastructure</div>
<div class="grid" id="infra-grid"></div>
</div>
<script>
const DEPTS=[
{id:'ceo',name:'CEO Office',icon:'👑',color:'#f59e0b',agents:['CEO Brain','Decision','Budget','Strategy','Hiring','Review'],pipeline:['Decision','Orchestration','TaskMgr','Intro','Brief'],output:'1 brief/j',metric:'Leadership'},
{id:'sal',name:'Prospect & Sales',icon:'🎯',color:'#ef4444',agents:['Leads','Qualify','Outreach','Convert','Close','Ethica','Analyst','Writer','Proposal','Contract'],pipeline:['LeadForge','Outreach','MailWarm','Proposal'],output:'1052 leads',metric:'B2B Pipeline'},
{id:'con',name:'Consulting',icon:'💼',color:'#8b5cf6',agents:['Architect','Planner','DeerFlow','Critic','Translate','Academy','ECC-36','Persona-6'],pipeline:['Analyse','Design','Process','Deliver','Support'],output:'3 proposals',metric:'SAP/Cloud/IA'},
{id:'dev',name:'Dev Lab',icon:'⚡',color:'#3b82f6',agents:['FullCode','Review','Test','Deploy','Mauricio','Debugger','Designer','WEDROID','Simplifier','Blueprint','DevForge'],pipeline:['Code','Review','Test','Deploy'],output:'12 deploys/j',metric:'CI/CD'},
{id:'srv',name:'Infrastructure',icon:'🏗️',color:'#06b6d4',agents:['Watchdog','Guardian','Blade','GitMaster','Loki','Monitor','Fix','Discover','Verify','Report'],pipeline:['Watch','Alert','Fix','Report'],output:'99.9% uptime',metric:'S204+S95+S151'},
{id:'sec',name:'Security',icon:'🛡️',color:'#ef4444',agents:['Security','Verifier','TruffleHog','DetectSecrets','KeyHacks','shhgit','GitDorking','Nuclei'],pipeline:['Scan','Audit','Patch','Lock'],output:'0 CVE',metric:'5 scanners'},
{id:'qa',name:'QA / L99',icon:'🧪',color:'#10b981',agents:['QA','Testing','Tracer','Scientist','L99','Plan','Execute','Analyse','Report','Fix'],pipeline:['Plan','Run','Report','Ship'],output:'148 PASS',metric:'153/153'},
{id:'pha',name:'Pharma & Ethica',icon:'💊',color:'#ec4899',agents:['Explore','DabaDoc','MiroFish','Validate','Enrich','Campaign','Ship'],pipeline:['Scrape','Enrich','Campaign','Ship'],output:'132.7K HCPs',metric:'DZ+MA+TN'},
{id:'ops',name:'Monitor',icon:'📊',color:'#f59e0b',agents:['TrustMRR','Grafana','Alert','Ortho','Dashboard'],pipeline:['Watch','Alert','Fix','Report'],output:'7.7K opens',metric:'1394 stats'},
{id:'cron',name:'Automation / Crons',icon:'⏰',color:'#f97316',agents:['EthicaCron','B2BCron','NonRegCron','BackupCron','OSSChainCron','L99AliveCron','GuardianCron','SecretScanCron','KeySyncCron'],pipeline:['Ethica','B2B','NonReg','Backup'],output:'50+ crons',metric:'24/7 auto'},
{id:'mta',name:'Email MTA',icon:'📧',color:'#6366f1',agents:['PMTA :25','KumoMTA :587','Postfix :2525'],pipeline:['PMTA','KumoMTA','Postfix','Deliver'],output:'7.7K opens',metric:'3M contacts'},
{id:'ai',name:'AI Engine',icon:'🧠',color:'#8b5cf6',agents:['Groq','Cerebras','MistralAI','SambaNovaAI','AlibabaQwen','NVIDIA-GLM5','Ollama','Sovereign','ClaudeCode','OpenWebUI','Lyria3','SunoAI'],pipeline:['Ingest','Route','Infer','Validate','Deliver'],output:'12 models',metric:'6 providers'},
{id:'saas',name:'SaaS Products',icon:'📦',color:'#10b981',agents:['LeadForge','OutreachAI','MailWarm','ProposalAI','WEVIA PUBLIC','Manager','WhatsApp API'],pipeline:['Build','Launch','Sell','Support','Scale'],output:'28 tools',metric:'7 products'},
{id:'intg',name:'OSS Integration',icon:'🔗',color:'#06b6d4',agents:['BrowserUse','OpenClaw','Goose','AIOS','Dify','Mastra','EvoMaster','Activepieces','AEGIS','Prometheus','CrewAI','LangChain','Scrapy','Supermemory','SkillSmith','Flowise','HuggingFace','Langflow','LibreChat','llama-cpp'],pipeline:['Discover','Evaluate','Wire','Test','Deploy'],output:'685 tools',metric:'22/22 INTG'},
{id:'dock',name:'Docker / Services',icon:'🐳',color:'#2563eb',agents:['Authentik x3','Plausible x3','Uptime-Kuma','Mattermost','SearXNG','Loki','Twenty-Redis','Paperclip','OpenWebUI','Flowise','Vaultwarden','n8n','Qdrant','Redis','Sovereign','CrowdSec'],pipeline:['Start','Configure','Monitor','Scale','Update'],output:'20 dock',metric:'19 UP'},
{id:'wevia',name:'WEVIA Suite',icon:'🤖',color:'#ec4899',agents:['WEVCODE','WEVIA Life','WEVIAGateway','TTS','MermaidGen','L99','ClaudeSync'],pipeline:['Chat','Code','Life','Gateway'],output:'200/j',metric:'71 modules'},
{id:'plat',name:'Platform',icon:'🔧',color:'#0d9488',agents:['SkillsRAG','PromptsLib','CodeWiki','AIBench','ModelScope','OSSDiscover','GHGrab','AgentShield','Obsidian'],pipeline:['Skills','Prompts','Wiki','Bench'],output:'4414 sk',metric:'528 skills'},
{id:'n8n',name:'n8n Workflows',icon:'⚙',color:'#3b82f6',agents:['n8n-EthicaHCP','n8n-B2BLeads','n8n-NonReg','n8n-Sovereign','n8n-WhatsApp','n8n-EmailDrip','n8n-OSSSync','n8n-DeerFlow','n8n-Paperclip','n8n-AzureAD','n8n-Guardian','n8n-SecretScan','n8n-KeySync','n8n-L99Alive','n8n-Backup'],pipeline:['Trigger','Process','Transform','Output'],output:'15 WF',metric:'13 active'},
{id:'wire',name:'TO WIRE',icon:'🔌',color:'#f97316',agents:['OVH SMS','ListMonk','NoVNC'],pipeline:['Commit','Config','Test','Activate'],output:'3 TODO',metric:'Needs creds'},
{id:'dorm',name:'Dormants',icon:'💤',color:'#6b7280',agents:['vLLM→Colab','LocalAI→HF','AutoGen→Eval','AnythingLLM','Wazuh','LlamaIndex'],pipeline:['Clone','Evaluate','Wire','Activate'],output:'6 wait',metric:'GPU/eval'},
];
function renderDepts(container,depts){
const g=document.getElementById(container);
g.innerHTML='';
depts.forEach(d=>{
const agents=d.agents.map(a=>{
const isN8n=a.startsWith('n8n-');
const isCron=a.includes('Cron');
const bg=isN8n?'rgba(59,130,246,.15)':isCron?'rgba(249,115,22,.15)':`rgba(${hexToRgb(d.color)},.12)`;
const fg=isN8n?'#60a5fa':isCron?'#fb923c':d.color;
return `<span class="agent" style="background:${bg};color:${fg}">${a}${isN8n?'<span class="n8n-tag">n8n</span>':''}</span>`;
}).join('');
const pipe=d.pipeline.map((s,i)=>`<span class="pipe-step">${i+1}. ${s}</span>${i<d.pipeline.length-1?'<span class="pipe-arrow">→</span>':''}`).join('');
g.innerHTML+=`<div class="dept">
<div class="dept-head"><h3>${d.icon} ${d.name} <span class="cnt">${d.agents.length}</span></h3><span class="badge" style="background:${d.color}20;color:${d.color}">${d.metric}</span></div>
<div class="dept-body">${agents}</div>
<div class="pipeline">${pipe}</div>
<div class="output"><span class="status-dot green"></span> OUTPUT: <span class="metric" style="color:${d.color}">${d.output}</span></div>
</div>`;
});
}
function hexToRgb(h){const r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16);return`${r},${g},${b}`}
const N8N_FLOWS=[
{name:'Ethica HCP Enrichment',schedule:'*/6h',nodes:12,status:'active',desc:'DabaDoc scrape → enrich tel/email → Telegram alert'},
{name:'B2B Lead Generation',schedule:'*/4h',nodes:8,status:'active',desc:'LinkedIn → email pattern → CRM → outbound sequence'},
{name:'NonReg Watchdog',schedule:'6h/18h',nodes:6,status:'active',desc:'153 tests → Telegram + Mattermost → L99 update'},
{name:'Sovereign AI Router',schedule:'Webhook',nodes:5,status:'active',desc:'Request → Ollama/Cerebras/Groq → format Anthropic'},
{name:'WhatsApp Campaign',schedule:'Manual',nodes:7,status:'ready',desc:'HCP list → template → Meta API → track delivery'},
{name:'Email Drip DZ+MA+TN',schedule:'*/5min',nodes:9,status:'active',desc:'Queue → KumoMTA → track opens/clicks → re-engage'},
{name:'OSS Discovery Sync',schedule:'*/6h',nodes:6,status:'active',desc:'GitHub scan → score → wire → Paperclip sync'},
{name:'DeerFlow Research',schedule:'Webhook',nodes:8,status:'active',desc:'Query → 528 skills → Groq → synthesize → report'},
{name:'Paperclip Chain',schedule:'API',nodes:10,status:'active',desc:'CEO heartbeat → agents → tools → execute → report'},
{name:'Azure AD O365',schedule:'Daily',nodes:5,status:'active',desc:'6 tenants → token refresh → 1311 accounts sync'},
{name:'Guardian Auto-Heal',schedule:'*/5min',nodes:4,status:'active',desc:'chattr check → service health → disk → auto-fix'},
{name:'Secret Scanner',schedule:'Sun 3am',nodes:5,status:'active',desc:'TruffleHog → detect-secrets → dorking → report'},
{name:'Key Sync',schedule:'*/6h',nodes:4,status:'active',desc:'secrets.env → inventory → validate → alert expired'},
{name:'L99 Alive Monitor',schedule:'*/30min',nodes:7,status:'active',desc:'14 pages → Playwright → screenshot → state update'},
{name:'Backup GOLD',schedule:'4am',nodes:5,status:'active',desc:'PG dump → vault → S95 → verify → clean old'},
];
function renderN8n(){
const g=document.getElementById('n8n-grid');
g.innerHTML='';
N8N_FLOWS.forEach(f=>{
const st=f.status==='active'?'green':'orange';
g.innerHTML+=`<div class="dept">
<div class="dept-head"><h3>⚙ ${f.name} <span class="n8n-tag">n8n</span></h3><span class="badge" style="background:rgba(59,130,246,.2);color:#60a5fa">${f.schedule}</span></div>
<div style="padding:10px 16px;font-size:12px;color:var(--dim)">${f.desc}</div>
<div class="output"><span class="status-dot ${st}"></span> ${f.nodes} nodes — <span class="metric" style="color:var(--accent)">${f.status.toUpperCase()}</span></div>
</div>`;
});
}
const INFRA=[
{name:'S204 (204.168.152.13)',status:'UP',details:'Hetzner AX102 · 150G SSD · 84% used · 24G free · 20 Docker · Nginx+PHP8.5+PG13 · Ollama 7 models'},
{name:'S95 (95.216.167.89)',status:'UP',details:'Hetzner · Apache+PHP8.4 · PG13 · 12 schemas 619 tables · PMTA+KumoMTA+Postfix · 192 Arsenal · 40 crons'},
{name:'S151 (151.80.235.110)',status:'UP',details:'OVH · OpenClaw+Ollama · Tracking relay · 45% disk · Redis+PG+Nginx'},
{name:'Blade (Razer)',status:'ONLINE',details:'Windows · Claude Code v2.1.89 · Sentinel v2.4 · GLM-5 · 34 capabilities'},
{name:'S88 (88.198.4.195)',status:'DEAD',details:'GPU mort · Hetzner ANNULÉ · -45€/mois économisés · Archives dans vault'},
{name:'Sovereign API (:4000)',status:'UP',details:'FastAPI · Ollama PRIMARY → Cerebras → Groq fallback · Anthropic Messages API'},
{name:'Paperclip (:3100)',status:'UP',details:'150 agents · 520 files · 747KB instructions · CEO org chart'},
{name:'DeerFlow',status:'UP',details:'528 skills · 3 systemd · Groq primary · Mattermost alerts'},
];
function renderInfra(){
const g=document.getElementById('infra-grid');
g.innerHTML='';
INFRA.forEach(s=>{
const color=s.status==='UP'||s.status==='ONLINE'?'var(--green)':s.status==='DEAD'?'var(--red)':'var(--orange)';
g.innerHTML+=`<div class="dept">
<div class="dept-head"><h3>🖥️ ${s.name}</h3><span class="badge" style="background:${color}20;color:${color}">${s.status}</span></div>
<div style="padding:10px 16px;font-size:12px;color:var(--dim)">${s.details}</div>
</div>`;
});
}
function showView(v){
['overview','agents','n8n','infra'].forEach(x=>document.getElementById('view-'+x).style.display='none');
document.getElementById('view-'+v).style.display='block';
document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
event.target.classList.add('active');
if(v==='n8n')renderN8n();
if(v==='infra')renderInfra();
if(v==='agents')renderDepts('agent-grid',DEPTS);
}
renderDepts('dept-grid',DEPTS);
</script>
<!-- WTP-GAP-FILL-V1 (doctrine 90-v2 gap-fill showcase, 18avr 2026) -->
<style>
.wtp-gapfill-banner{position:fixed;bottom:0;left:0;right:0;z-index:99999;background:linear-gradient(90deg,#05060a,#0b0d15 20%,#181d2e 50%,#0b0d15 80%,#05060a);border-top:2px solid #14b8a6;color:#e2e8f0;padding:10px 16px;font-family:Inter,system-ui,-apple-system,sans-serif;font-size:11.5px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;box-shadow:0 -10px 30px rgba(20,184,166,.28)}
.wtp-gapfill-banner a{color:#5eead4;text-decoration:none;font-weight:600;transition:color .15s}
.wtp-gapfill-banner a:hover{color:#22d3ee}
.wtp-gapfill-banner .pill{padding:2px 9px;background:rgba(99,102,241,.14);color:#a5b4fc;border-radius:10px;font-size:10.5px;font-family:JetBrains Mono,monospace;font-weight:600}
.wtp-gapfill-banner .pill.new{background:rgba(20,184,166,.22);color:#5eead4}
.wtp-gapfill-banner .pill.hot{background:rgba(236,72,153,.22);color:#f472b6}
.wtp-gapfill-banner .close{margin-left:auto;cursor:pointer;color:#64748b;padding:0 8px;font-size:16px;line-height:1;border:1px solid #334155;border-radius:4px}
.wtp-gapfill-banner .close:hover{color:#e2e8f0;border-color:#64748b}
.wtp-gapfill-banner.hidden{display:none}
@media(max-width:768px){.wtp-gapfill-banner{font-size:10px;padding:7px 10px;gap:8px}}
</style>
<div class="wtp-gapfill-banner" id="wtpGapFillBanner">
<span>🎯 <strong>WEVAL Agents Gap-Fill ERP</strong></span>
<span class="pill hot">45 gaps</span>
<span class="pill">SAP · Oracle · NetSuite · Dynamics</span>
<span class="pill new">🆕 Meeting Rooms</span>
<span class="pill new">🆕 Lean 6 Sigma</span>
<span id="wtp-gfb-metrics" class="pill">— chargement —</span>
<a href="/weval-technology-platform.html">→ WTP Portal (16 mod)</a>
<a href="/enterprise-model.html">Enterprise Model</a>
<a href="/api/weval-agents-gap-fill-manifest.json" target="_blank">📋 Manifest</a>
<span class="close" onclick="document.getElementById("wtpGapFillBanner").classList.add("hidden");localStorage.setItem("wtpGapFillHidden","1")">×</span>
</div>
<script>
(async()=>{
if(localStorage.getItem("wtpGapFillHidden")==="1"){document.getElementById("wtpGapFillBanner").classList.add("hidden");return;}
try{
const r=await fetch("/api/source-of-truth.json?t="+Date.now());
const d=await r.json();
const el=document.getElementById("wtp-gfb-metrics");
if(el)el.textContent=(d.ethica_total||"?")+" HCPs · "+(d.nonreg||"?")+" · "+(d.providers_count||"?")+" IA · "+(d.agents_count||"?")+" agents · "+(d.docker_running||"?")+" 🐳";
}catch(e){}
})();
</script>
<!-- WTP-D90V2-ENRICH-BANNER (doctrine 90-v2, 17avr 2026) -->
<style>
.wtp-enrich-banner{position:fixed;bottom:0;left:0;right:0;z-index:9999;background:linear-gradient(90deg,#0b0d15,#181d2e,#0b0d15);border-top:2px solid #14b8a6;color:#e2e8f0;padding:9px 18px;font-family:'JetBrains Mono',monospace,-apple-system,system-ui;font-size:11.5px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;box-shadow:0 -8px 24px rgba(20,184,166,.25)}
.wtp-enrich-banner a{color:#14b8a6;text-decoration:none;font-weight:600}
.wtp-enrich-banner a:hover{color:#22d3ee}
.wtp-enrich-banner .pill{padding:2px 8px;background:rgba(99,102,241,.15);color:#a5b4fc;border-radius:10px;font-size:10.5px}
.wtp-enrich-banner .pill.new{background:rgba(20,184,166,.2);color:#5eead4}
.wtp-enrich-banner .close{margin-left:auto;cursor:pointer;color:#64748b;padding:0 6px;font-size:14px}
.wtp-enrich-banner .close:hover{color:#e2e8f0}
.wtp-enrich-banner.hidden{display:none}
@media(max-width:768px){.wtp-enrich-banner{font-size:10px;padding:6px 10px}}
</style>
<div class="wtp-enrich-banner" id="wtpEnrichBanner">
<span>🏛️ <strong>Enterprise Model 16 depts</strong></span>
<span class="pill new">🆕 Meeting Rooms</span>
<span class="pill new">🆕 Lean 6 Sigma</span>
<span id="wtp-eb-metrics" class="pill">— chargement —</span>
<a href="/weval-technology-platform.html">→ WEVAL Technology Platform (16 modules)</a>
<a href="/enterprise-model.html">Enterprise Model</a>
<a href="/wevia-master.html">WEVIA Master</a>
<span class="close" onclick="document.getElementById('wtpEnrichBanner').classList.add('hidden')">×</span>
</div>
<script>
(async()=>{try{const r=await fetch('/api/source-of-truth.json?t='+Date.now());const d=await r.json();const el=document.getElementById('wtp-eb-metrics');if(el)el.textContent=(d.ethica_total||'?')+' HCPs · '+(d.nonreg||'?')+' · '+(d.providers_count||'?')+' IA · '+(d.docker_running||'?')+' 🐳 · '+(d.subdomains_live||'?')+' subdomains';}catch(e){}})();
</script>
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
<script>
(function(){
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
var d = document;
var m = d.createElement('div');
m.id = 'opus-udrill';
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
var inner = d.createElement('div');
inner.id = 'opus-udrill-in';
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
inner.addEventListener('click', function(e){ e.stopPropagation(); });
m.appendChild(inner);
m.addEventListener('click', function(){ m.style.display='none'; });
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
(d.body || d.documentElement).appendChild(m);
function openCard(card) {
// Clone card content + show close btn + increase font-size
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
inner.innerHTML = html;
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
m.style.display = 'flex';
}
function wire(root) {
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
var cards = root.querySelectorAll(sels);
for (var i = 0; i < cards.length; i++) {
var c = cards[i];
if (c.__opusWired) continue;
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
var r = c.getBoundingClientRect();
if (r.width < 60 || r.height < 40) continue;
c.__opusWired = true;
c.style.cursor = 'pointer';
c.setAttribute('role','button');
c.setAttribute('tabindex','0');
c.addEventListener('click', function(ev){
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
if (ev.target.closest('a,button,input,select')) return;
ev.preventDefault(); ev.stopPropagation();
openCard(this);
});
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
}
}
// Initial + mutation observer
var initRun = function(){ wire(d.body || d.documentElement); };
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
else initRun();
var mo = new MutationObserver(function(muts){
var newCard = false;
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
if (newCard) initRun();
});
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
})();
</script>
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
<!-- === OPUS HONEST NR/L99 OVERLAY v1 19avr - append-only doctrine #14 === -->
<script>
(function(){
if (window.__opusHonestOverlay) return; window.__opusHonestOverlay = true;
async function updateHonestValues(){
try {
const r = await fetch('/api/l99-honest.php', {cache:'no-store'});
const d = await r.json();
if (!d.ok) return;
const realNR = `${d.combined.pass}/${d.combined.total}`;
const realSigma = d.sigma;
// Find elements showing the myth values
const mythRegex = /(153\/153|304\/304|NR status 153\/153|L99 status 304\/304|NR 153\/153|L99 304\/304)/g;
// Walk text nodes
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
const toReplace = [];
let node;
while (node = walker.nextNode()) {
if (node.nodeValue && mythRegex.test(node.nodeValue)) toReplace.push(node);
}
toReplace.forEach(textNode => {
const parent = textNode.parentNode;
if (!parent || parent.hasAttribute('data-opus-honest-applied')) return;
const newText = textNode.nodeValue.replace(/153\/153/g, realNR).replace(/304\/304/g, realNR);
textNode.nodeValue = newText;
parent.setAttribute('data-opus-honest-applied', '1');
});
// Add a small badge bottom-right showing honest live status
if (!document.getElementById('opus-honest-badge')) {
const b = document.createElement('div');
b.id = 'opus-honest-badge';
b.style.cssText = 'position:fixed;bottom:12px;right:12px;background:linear-gradient(90deg,#14b8a6,#a855f7);color:#05060a;padding:6px 12px;font:10px/1.3 Inter,system-ui,sans-serif;font-weight:700;border-radius:8px;z-index:99993;box-shadow:0 4px 12px rgba(0,0,0,0.3);cursor:pointer;max-width:280px';
b.title = 'Cliquer pour détails';
b.innerHTML = `✓ NR ${realNR} · ${realSigma} live`;
b.onclick = () => {
alert(`HONEST NonReg (doctrine #4):\n\nmaster: ${d.master.pass}/${d.master.total}\nopus: ${d.opus.pass}/${d.opus.total}\ncombined: ${realNR}\nsigma: ${realSigma}\n\n${d.myth_153}\n${d.myth_304}`);
};
document.body.appendChild(b);
}
} catch(e){console.error('L99-honest fetch error:', e);}
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateHonestValues);
else updateHonestValues();
setInterval(updateHonestValues, 90000);
})();
</script>
<!-- === OPUS HONEST END === -->
</body>
</html>