Files
html/api/wevia-coherence-scan-v77.php
2026-04-18 12:20:02 +02:00

289 lines
11 KiB
PHP

<?php
// V77 WEVIA Coherence & Problem Scanner
// Systematically audits the entire system for: incoherences, broken KPIs, missing agents,
// expired tokens, dead links, stale data, config drift, doctrine violations
header("Content-Type: application/json");
$action = $_REQUEST["action"] ?? "scan";
function run_shell($cmd, $timeout = 10) {
return trim(@shell_exec("timeout " . intval($timeout) . " " . $cmd . " 2>&1") ?: "");
}
function safe_json($path) {
if (!is_readable($path)) return null;
return json_decode(@file_get_contents($path), true);
}
$issues = [];
$kpis_to_optimize = [];
$missing_agents = [];
$incoherences = [];
// ============================================
// ISSUE CHECKS (60+ systematic checks)
// ============================================
// 1. Stale data check - any *-latest.json files > 72h old
foreach (glob("/var/www/html/api/*-latest.json") ?: [] as $f) {
$age = (time() - filemtime($f)) / 3600;
if ($age > 72) {
$issues[] = ["sev" => "warn", "cat" => "stale_data", "file" => basename($f), "age_hours" => round($age, 1)];
}
}
// 2. GOLD backup explosion check
$golds = count(glob("/var/www/html/*.GOLD-*") ?: []) + count(glob("/var/www/html/api/*.GOLD-*") ?: []);
if ($golds > 500) {
$issues[] = ["sev" => "warn", "cat" => "gold_bloat", "count" => $golds];
}
// 3. Expired secrets check (WhatsApp token, GitHub PAT from memory)
$secrets = @file_get_contents("/etc/weval/secrets.env") ?: "";
if (strpos($secrets, "WHATSAPP_TOKEN_EXPIRED") !== false || strpos($secrets, "# expired") !== false) {
$issues[] = ["sev" => "high", "cat" => "expired_secret", "note" => "WhatsApp token needs renewal"];
}
// 4. Disk usage check
$disk = run_shell("df -h / | tail -1 | awk '{print $5}' | tr -d %");
if (intval($disk) > 85) {
$issues[] = ["sev" => "high", "cat" => "disk_high", "pct" => $disk];
}
// 5. Docker containers unhealthy
$docker_unhealthy = run_shell("docker ps --format '{{.Names}} {{.Status}}' | grep -c -i unhealthy");
if (intval($docker_unhealthy) > 0) {
$issues[] = ["sev" => "high", "cat" => "docker_unhealthy", "count" => $docker_unhealthy];
}
// 6. PHP FPM not active
$fpm_status = run_shell("systemctl is-active php8.4-fpm 2>&1");
if (strpos($fpm_status, "active") === false) {
$issues[] = ["sev" => "critical", "cat" => "fpm_down", "status" => $fpm_status];
}
// 7. nginx not active
$nginx_status = run_shell("systemctl is-active nginx 2>&1");
if (strpos($nginx_status, "active") === false) {
$issues[] = ["sev" => "critical", "cat" => "nginx_down", "status" => $nginx_status];
}
// 8. Qdrant unreachable
$qdrant = run_shell("curl -sk --max-time 3 http://127.0.0.1:6333/collections -o /dev/null -w '%{http_code}'");
if ($qdrant !== "200") {
$issues[] = ["sev" => "high", "cat" => "qdrant_down", "code" => $qdrant];
}
// 9. Ollama unreachable (optional)
$ollama1 = run_shell("curl -sk --max-time 3 http://127.0.0.1:11434/api/tags -o /dev/null -w '%{http_code}'");
$ollama2 = run_shell("curl -sk --max-time 3 http://127.0.0.1:11435/api/tags -o /dev/null -w '%{http_code}'");
if ($ollama1 !== "200" && $ollama2 !== "200") {
$issues[] = ["sev" => "low", "cat" => "ollama_down", "note" => "11434 and 11435 both down"];
}
// 10. Cron crontab emptiness check
$crons = intval(run_shell("crontab -l 2>/dev/null | grep -vE '^#|^$' | wc -l"));
if ($crons < 10) {
$issues[] = ["sev" => "high", "cat" => "crontab_sparse", "count" => $crons];
}
// 11. Agent stubs verification
$stubs = glob("/var/www/html/api/agent-stubs/agent_*.php") ?: [];
if (count($stubs) < 45) {
$missing_agents[] = ["reason" => "stub_count_drift", "expected" => 45, "actual" => count($stubs)];
}
// 12. Registry has 500+ tools
$reg = safe_json("/var/www/html/api/wevia-tool-registry.json");
$reg_tools = $reg["tools"] ?? $reg ?? [];
if (count($reg_tools) < 500) {
$issues[] = ["sev" => "high", "cat" => "registry_shrunk", "count" => count($reg_tools)];
}
// 13. Dormants top needs - these are MISSING AGENTS
$dormants = json_decode(run_shell("curl -sk --max-time 5 'http://127.0.0.1/api/oss-discovery.php?k=WEVADS2026&action=dormants' -H 'Host: weval-consulting.com'"), true);
$by_need = $dormants["by_need"] ?? [];
arsort($by_need);
foreach (array_slice($by_need, 0, 5, true) as $need => $count) {
if ($count > 50) {
$missing_agents[] = ["need_category" => $need, "dormants_count" => $count, "suggested_agent" => "v77_agent_" . $need];
}
}
// 14. Ethica HCP count check
$ethica = json_decode(run_shell("curl -sk --max-time 5 'http://127.0.0.1/api/ethica-stats-api.php' -H 'Host: weval-consulting.com'"), true);
if (($ethica["total"] ?? 0) < 100000) {
$issues[] = ["sev" => "high", "cat" => "hcp_low", "count" => $ethica["total"] ?? 0];
$kpis_to_optimize[] = ["kpi" => "ethica_hcp_coverage", "current" => $ethica["total"] ?? 0, "target" => 200000];
}
// 15. Skills activation rate
$skills = json_decode(run_shell("curl -sk --max-time 5 'http://127.0.0.1/api/oss-discovery.php?k=WEVADS2026&action=skills' -H 'Host: weval-consulting.com'"), true);
$active_rate = ($skills["total"] ?? 0) > 0 ? 100.0 * ($skills["active"] ?? 0) / $skills["total"] : 0;
if ($active_rate < 99) {
$kpis_to_optimize[] = ["kpi" => "skills_activation_rate", "current_pct" => round($active_rate, 2), "target_pct" => 99.99];
}
// 16. Test cascade coverage
$test_files = ["nonreg", "nonreg-reg67", "nonreg-reg68", "nonreg-reg69", "nonreg-reg70", "nonreg-reg71", "v74-e2e", "v75-deep-e2e", "v76-chrome-e2e"];
$missing_tests = [];
foreach ($test_files as $tf) {
$p = "/var/www/html/api/$tf-latest.json";
if (!file_exists($p)) {
$missing_tests[] = $tf;
} else {
$d = json_decode(file_get_contents($p), true);
$score = $d["score"] ?? 0;
if ($score < 100) {
$issues[] = ["sev" => "warn", "cat" => "test_regression", "test" => $tf, "score" => $score];
}
}
}
if ($missing_tests) {
$issues[] = ["sev" => "high", "cat" => "missing_test_layers", "tests" => $missing_tests];
}
// 17. INCOHERENCES - data drift across sources
$mega = json_decode(run_shell("curl -sk --max-time 5 'http://127.0.0.1/api/wevia-mega-agents.php?action=counts' -H 'Host: weval-consulting.com'"), true);
if ($mega) {
$mega_total = $mega["total_aggregated"] ?? 0;
$manifest_live = $mega["manifest_total_live"] ?? 0;
if ($manifest_live - $mega_total > 500) {
$incoherences[] = [
"type" => "agent_count_mismatch",
"mega_structured" => $mega_total,
"manifest_declared" => $manifest_live,
"gap" => $manifest_live - $mega_total,
"resolution" => "Either over-declared in manifest or under-implemented in reality"
];
}
}
// 18. Training UI version label coherence
$training_html = @file_get_contents("/var/www/html/wevia-training.html") ?: "";
if (strpos($training_html, "V44 · Training") !== false && strpos($training_html, "V77") === false) {
$incoherences[] = [
"type" => "ui_version_stale",
"current_label" => "V44",
"latest_delivered" => "V77",
"location" => "wevia-training.html header"
];
}
// 19. Master control dashboard - are all tabs wired?
$known_tabs = ["dashboard", "intents", "training", "skills", "brain", "custom", "benchmark",
"brain-mon", "dormants", "acquis", "wevia-brain", "l6s-toc", "cognitive",
"kb-doctrines", "ia-building", "honest-tracker", "qahub", "risk-plan",
"multiagent-v72", "architecture", "logs"];
$missing_tabs = [];
foreach ($known_tabs as $tab) {
if (strpos($training_html, "data-view=\"$tab\"") === false) {
$missing_tabs[] = $tab;
}
}
if ($missing_tabs) {
$issues[] = ["sev" => "warn", "cat" => "missing_tabs", "tabs" => $missing_tabs];
}
// 20. Git dirty state check
$git_dirty = intval(run_shell("cd /var/www/html && git status --porcelain 2>/dev/null | wc -l"));
if ($git_dirty > 50) {
$issues[] = ["sev" => "warn", "cat" => "git_dirty_high", "count" => $git_dirty];
}
// ============================================
// KPIs TO OPTIMIZE (extracted from data)
// ============================================
// KPI1: Intents wired (from V75 orchestration)
$v75_wire = json_decode(run_shell("curl -sk --max-time 5 'http://127.0.0.1/api/wevia-orchestration-v75.php?action=wire' -H 'Host: weval-consulting.com'"), true);
if ($v75_wire) {
$stubs_cnt = $v75_wire["wevia_master_controls"]["agent_stubs"] ?? 0;
if ($stubs_cnt < 100) {
$kpis_to_optimize[] = [
"kpi" => "agent_stubs_total",
"current" => $stubs_cnt,
"target" => 100,
"gap" => 100 - $stubs_cnt,
"action" => "Create more agent stubs via agent_factory"
];
}
$dorm_cnt = $v75_wire["wevia_master_controls"]["dormants"]["total"] ?? 0;
if ($dorm_cnt > 500) {
$kpis_to_optimize[] = [
"kpi" => "dormants_activation",
"current_dormants" => $dorm_cnt,
"target_activation_pct" => 20,
"action" => "Activate top 150 dormants into live skills"
];
}
}
// ============================================
// COMPILE REPORT
// ============================================
$severity_count = ["critical" => 0, "high" => 0, "warn" => 0, "low" => 0];
foreach ($issues as $i) {
$sev = $i["sev"] ?? "warn";
$severity_count[$sev] = ($severity_count[$sev] ?? 0) + 1;
}
if ($action === "scan") {
echo json_encode([
"ok" => true,
"version" => "V77-coherence-scanner",
"ts" => date("c"),
"summary" => [
"total_issues" => count($issues),
"by_severity" => $severity_count,
"incoherences" => count($incoherences),
"missing_agents" => count($missing_agents),
"kpis_to_optimize" => count($kpis_to_optimize)
],
"issues" => $issues,
"incoherences" => $incoherences,
"missing_agents" => $missing_agents,
"kpis_to_optimize" => $kpis_to_optimize
], JSON_PRETTY_PRINT);
exit;
}
if ($action === "summary") {
echo json_encode([
"ok" => true,
"ts" => date("c"),
"issues_count" => count($issues),
"by_severity" => $severity_count,
"incoherences_count" => count($incoherences),
"missing_agents_count" => count($missing_agents),
"kpis_to_optimize_count" => count($kpis_to_optimize),
"top_3_issues" => array_slice($issues, 0, 3),
"top_incoherence" => $incoherences[0] ?? null
], JSON_PRETTY_PRINT);
exit;
}
if ($action === "issues_only") {
echo json_encode(["ok" => true, "issues" => $issues, "count" => count($issues)], JSON_PRETTY_PRINT);
exit;
}
if ($action === "incoherences_only") {
echo json_encode(["ok" => true, "incoherences" => $incoherences, "count" => count($incoherences)], JSON_PRETTY_PRINT);
exit;
}
if ($action === "missing_agents") {
echo json_encode(["ok" => true, "missing_agents" => $missing_agents, "count" => count($missing_agents)], JSON_PRETTY_PRINT);
exit;
}
if ($action === "kpis") {
echo json_encode(["ok" => true, "kpis_to_optimize" => $kpis_to_optimize, "count" => count($kpis_to_optimize)], JSON_PRETTY_PRINT);
exit;
}
echo json_encode(["ok" => false, "error" => "unknown action", "valid" => ["scan","summary","issues_only","incoherences_only","missing_agents","kpis"]]);