auto-sync-opus46

This commit is contained in:
opus-wire
2026-04-20 14:29:18 +02:00
parent 4e45cfabb6
commit 275de36f0a
60 changed files with 627 additions and 6 deletions

53
exhaustive_audit.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
echo "=== 1. NR cache fresh ==="
AGE=$(($(date +%s) - $(stat -c %Y /tmp/l99-honest-cache.json 2>/dev/null || echo 0)))
echo "age: ${AGE}s"
if [ $AGE -gt 1800 ]; then
rm -f /tmp/l99-honest-cache.json /tmp/l99-honest.lock
nohup bash /var/www/html/api/handlers/l99-honest-refresh.sh > /tmp/l99_v88.txt 2>&1 &
echo "REFRESH KICKED pid=$!"
fi
echo ""
echo "=== 2. WTP HTTP check ==="
curl -s "https://weval-consulting.com/weval-technology-platform.html" --max-time 10 -o /dev/null -w "WTP: HTTP=%{http_code} size=%{size_download} time=%{time_total}s\n"
echo ""
echo "=== 3. Recent 5xx count (last 1000 log lines) ==="
sudo -n tail -1000 /var/log/nginx/access.log 2>/dev/null | awk '$9 ~ /^5/ {c[$9]++} END {for (k in c) print k, c[k]}'
echo ""
echo "=== 4. Recent 404 count (last 1000 log lines) on /api/ ==="
sudo -n tail -1000 /var/log/nginx/access.log 2>/dev/null | awk '$9 == "404" && $7 ~ /^\/api\// {c[$7]++} END {for (k in c) print c[k], k}' | sort -rn | head -10
echo ""
echo "=== 5. PHP errors last 50 lines ==="
sudo -n tail -50 /var/log/php8.5-fpm.log 2>/dev/null | grep -v "NOTICE\|^$" | tail -10
echo ""
echo "=== 6. Long-running FPM children ==="
ps auxw | grep "php-fpm" | awk '$10 > "1:00" {print $2, $10, $11, $12}' | head -5
echo ""
echo "=== 7. Docker health ==="
docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null | grep -v "healthy\|Up [0-9]" | head -5
echo ""
echo "=== 8. Load avg ==="
uptime
echo ""
echo "=== 9. Memory ==="
free -h | head -2
echo ""
echo "=== 10. Critical API endpoints ==="
for ep in \
"/api/l99-honest.php" \
"/api/weval-archi-manifest.php" \
"/api/wevia-v64-departments-kpi.php" \
"/api/wevia-master-api.php" \
"/api/em-live-kpi.php"; do
T=$(curl -s "http://127.0.0.1${ep}" -H "Host: weval-consulting.com" --max-time 5 -o /dev/null -w "%{http_code} %{time_total}s")
echo "$ep -> $T"
done

60
fix_api_error.py Normal file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python3
path = "/etc/nginx/sites-enabled/weval-consulting"
with open(path, "rb") as f:
raw = f.read()
if b"location @api_error" in raw:
print("ALREADY")
exit(0)
# Find the FIRST "server {" and its closing "}"
# Server 1 goes from line 7 to line 55 per grep
# Insert @api_error definition BEFORE the closing "}" of server 1
# Find line "^}\n" that comes after line with "error_page 502 503 504 =503 @api_error"
# Pattern: first standalone closing brace after @api_error usage
# Split into lines with byte offsets
lines = raw.split(b"\n")
# Find @api_error first usage
api_err_line = None
for i, ln in enumerate(lines):
if b"@api_error" in ln:
api_err_line = i
break
# Find first standalone "}" after that
close_line = None
for i in range(api_err_line, len(lines)):
if lines[i].strip() == b"}":
close_line = i
break
if close_line is None:
print("NO_CLOSE")
exit(1)
# Insert @api_error location before close_line
insert = [
b"",
b" # V88: named location @api_error - JSON error for API FastCGI failures",
b" location @api_error {",
b" default_type application/json;",
b" return 503 '{\"ok\":false,\"error\":\"api_error\",\"upstream\":\"fpm\",\"msg\":\"service temporarily unavailable\"}';",
b" }",
b"",
]
lines = lines[:close_line] + insert + lines[close_line:]
new_raw = b"\n".join(lines)
with open(path, "wb") as f:
f.write(new_raw)
print(f"Inserted @api_error at line {close_line}")
print(f"Size: {len(raw)}{len(new_raw)}")
# Also insert in server 2 (HTTPS) if same issue
# Find second @api_error
idx2 = new_raw.find(b"@api_error", new_raw.find(b"@api_error") + 15)
# Check if server 2 needs it too (we check if @api_error location is present in server 2)
# For safety, insert also in HTTPS block

42
fix_api_error_v2.py Normal file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env python3
path = "/etc/nginx/sites-enabled/weval-consulting"
with open(path, "rb") as f:
raw = f.read()
# Check if server 1 has @api_error location
# Server 1 goes from line 7 to first "}" after line 33
lines = raw.split(b"\n")
# Line 6 = index 6 (0-indexed line 7)
# Find server 1 close - first standalone "}" after line 33
close_line = None
for i in range(33, 80): # Look between line 33 and ~80
if i < len(lines) and lines[i].strip() == b"}":
close_line = i
break
print(f"Server 1 close at line: {close_line+1}")
# Check if @api_error is already in server 1 (between lines 7-close_line)
server1 = b"\n".join(lines[6:close_line+1])
if b"location @api_error" in server1:
print("Server 1 already has @api_error")
exit(0)
# Insert location @api_error BEFORE close_line
insert = [
b"",
b" # V88: named location @api_error for server 1 (HTTP)",
b" location @api_error {",
b" default_type application/json;",
b" return 503 '{\"ok\":false,\"error\":\"api_error\",\"msg\":\"service temporarily unavailable\"}';",
b" }",
b"",
]
lines = lines[:close_line] + insert + lines[close_line:]
new_raw = b"\n".join(lines)
with open(path, "wb") as f:
f.write(new_raw)
print(f"Inserted @api_error at line {close_line+1}")
print(f"Size: {len(raw)}{len(new_raw)}")

47
fix_api_error_v3.py Normal file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env python3
path = "/etc/nginx/sites-enabled/weval-consulting"
with open(path, "rb") as f:
raw = f.read()
lines = raw.split(b"\n")
# Find server 1 end: last "}" BEFORE second "server {"
server_opens = []
for i, ln in enumerate(lines):
if ln.strip() == b"server {":
server_opens.append(i)
print(f"Server opens at lines: {[x+1 for x in server_opens]}")
# Server 1: lines[server_opens[0]] to last "}" before server_opens[1]
# Scan backwards from server_opens[1]-1 to find closing brace at col 0
server1_close = None
for i in range(server_opens[1]-1, server_opens[0], -1):
if lines[i].strip() == b"}":
server1_close = i
break
print(f"Server 1 close at line {server1_close+1}")
# Check if server 1 already has @api_error location
server1 = b"\n".join(lines[server_opens[0]:server1_close+1])
if b"location @api_error" in server1:
print("Server 1 already has @api_error - aborting")
exit(0)
insert = [
b"",
b" # V88: named location @api_error - JSON error for API FastCGI failures",
b" location @api_error {",
b" default_type application/json;",
b" return 503 '{\"ok\":false,\"error\":\"api_error\",\"msg\":\"service temporarily unavailable\"}';",
b" }",
b"",
]
lines = lines[:server1_close] + insert + lines[server1_close:]
new_raw = b"\n".join(lines)
with open(path, "wb") as f:
f.write(new_raw)
print(f"Inserted @api_error at line {server1_close+1}")
print(f"Size: {len(raw)}{len(new_raw)}")

44
fix_autoheal.py Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/env python3
# V88: Fix wevia-auto-heal (raise worker threshold) + wevia-master-autoheal (timings)
# Fix 1: auto-heal threshold
path1 = "/var/www/html/api/wevia-auto-heal.php"
with open(path1, "rb") as f:
raw1 = f.read()
if b"V88" not in raw1:
# Change threshold 50 → 180 (max is 140 total pools = safe headroom)
old = b"$w > 50"
new = b"$w > 180" # V88: raised from 50 to 180 (total max = 140 workers)
if old in raw1:
raw1 = raw1.replace(old, new, 1)
# Also skip the self-kill - instead just log + call FPM reload via systemctl
old_kill = b'shell_exec("killall -9 php-fpm8.5; sleep 2; systemctl start php8.5-fpm &")'
new_kill = b'/* V88: disabled self-kill. Use systemctl reload instead */ shell_exec("sudo -n systemctl reload php8.5-fpm 2>&1 > /tmp/fpm-reload.log &")'
if old_kill in raw1:
raw1 = raw1.replace(old_kill, new_kill, 1)
with open(path1, "wb") as f:
f.write(raw1)
print(f"auto-heal: size={len(raw1)}")
# Fix 2: master-autoheal timings
path2 = "/var/www/html/api/wevia-master-autoheal.php"
with open(path2, "rb") as f:
raw2 = f.read()
if b"V88 hardened" not in raw2:
old = b"<?php"
new = b"""<?php
// V88 hardened: limits to avoid fcgi timeout
@set_time_limit(60);
@ini_set('memory_limit', '256M');
@ini_set('max_execution_time', 60);
"""
if old in raw2 and raw2.count(b"V88 hardened") == 0:
idx = raw2.find(old)
raw2 = raw2[:idx] + new + raw2[idx+len(old):]
with open(path2, "wb") as f:
f.write(raw2)
print(f"master-autoheal: size={len(raw2)}")
print("DONE")

15
fix_em_live_ttl.py Normal file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env python3
path = "/var/www/html/api/em-live-kpi.php"
with open(path, "rb") as f:
raw = f.read()
# Change TTL 5s -> 60s
old = b"(time() - filemtime($_emcache)) < 5)"
new = b"(time() - filemtime($_emcache)) < 60)"
if old in raw:
raw = raw.replace(old, new, 1)
with open(path, "wb") as f:
f.write(raw)
print("TTL 5s -> 60s PATCHED")
else:
print("NOT_FOUND")

27
fix_fpm_dedup_all.py Normal file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env python3
path = "/etc/php/8.5/fpm/pool.d/www.conf"
with open(path, "rb") as f:
raw = f.read()
# Dedup all active pm.* lines
keywords = [b"pm.start_servers", b"pm.min_spare_servers", b"pm.max_spare_servers", b"pm.max_children"]
lines = raw.split(b'\n')
seen = {}
kept = []
for line in lines:
stripped = line.strip()
matched = None
for kw in keywords:
if stripped.startswith(kw + b" ") and not stripped.startswith(b";"):
matched = kw
break
if matched:
if matched in seen:
continue
seen[matched] = True
kept.append(line)
new_raw = b'\n'.join(kept)
with open(path, "wb") as f:
f.write(new_raw)
print(f"size: {len(raw)} -> {len(new_raw)}")

35
fix_searxng_proxy.py Normal file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env python3
path = "/var/www/html/api/searxng-proxy.php"
with open(path, "rb") as f:
raw = f.read()
if b"V88 hardened" in raw:
print("ALREADY")
exit(0)
# After <?php tag - add safety limits
old = b"<?php"
new = b"""<?php
// V88 hardened: limits + error handling
@set_time_limit(20);
@ini_set('memory_limit', '128M');
@ini_set('max_execution_time', 20);
"""
if old in raw and raw.count(b"V88 hardened") == 0:
idx = raw.find(old)
raw = raw[:idx] + new + raw[idx+len(old):]
# Also wrap curl_exec with error capture
old2 = b"$r = curl_exec($ch);\ncurl_close($ch);\necho $r ?: '{\"error\":\"searxng down\"}';"
new2 = b"""$r = curl_exec($ch);
$err = curl_error($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($r === false || $err) { echo json_encode(['error'=>'searxng down', 'curl_err'=>$err, 'http_code'=>$code]); exit; }
echo $r;"""
if old2 in raw:
raw = raw.replace(old2, new2, 1)
with open(path, "wb") as f:
f.write(raw)
print(f"Size: {len(raw)}")

13
install_l99_cron.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
# V88: Install L99 auto-refresh cron (15min interval)
CRONBAK=$(crontab -l 2>/dev/null)
echo "$CRONBAK" > /tmp/cron_before.txt
if echo "$CRONBAK" | grep -q "l99-honest-refresh.sh"; then
echo "ALREADY_CRONNED"
exit 0
fi
(echo "$CRONBAK"; \
echo "# V88 L99 honest auto-refresh every 15min (TTL 1200s = 20min)"; \
echo "*/15 * * * * timeout 700 bash /var/www/html/api/handlers/l99-honest-refresh.sh >> /var/log/l99-honest-cron.log 2>&1") | crontab -
echo "CRON_INSTALLED"
crontab -l | grep -i l99

View File

@@ -1,5 +1,5 @@
{ {
"timestamp": "2026-04-20T14:10:02.132388", "timestamp": "2026-04-20T14:25:02.558886",
"layers": { "layers": {
"DOCKER": { "DOCKER": {
"pass": 19, "pass": 19,
@@ -17,8 +17,8 @@
"pct": 100 "pct": 100
}, },
"CRONS": { "CRONS": {
"pass": 34, "pass": 35,
"total": 34, "total": 35,
"pct": 100 "pct": 100
}, },
"NONREG": { "NONREG": {
@@ -62,10 +62,10 @@
"pct": 100 "pct": 100
} }
}, },
"pass": 339, "pass": 340,
"fail": 0, "fail": 0,
"warn": 0, "warn": 0,
"total": 339, "total": 340,
"score": 100, "score": 100,
"videos": 32, "videos": 32,
"screenshots": 14, "screenshots": 14,

View File

@@ -0,0 +1,125 @@
[14:27:36] 🚀 L99-ALIVE v1.0 starting...
[14:27:36] Time: 2026-04-20T14:27:36.863459
[14:27:36] 🔍 PHASE 1: Detecting changes...
[14:27:36] Scanning HTML pages...
[14:27:37] ✅ [CHANGE-DETECT] changed 404.html — old=4749 new=8144
[14:27:37] ✅ [CHANGE-DETECT] new page acquired-dashboard.html — size=35604
[14:27:37] ✅ [CHANGE-DETECT] changed admin-saas.html — old=1683 new=1821
[14:27:38] ✅ [CHANGE-DETECT] changed admin-v2.html — old=1683 new=1821
[14:27:38] ✅ [CHANGE-DETECT] changed admin.html — old=1683 new=1821
[14:27:38] ✅ [CHANGE-DETECT] new page agent-roi-simulator.html — size=33588
[14:27:38] ✅ [CHANGE-DETECT] changed agents-3d.html — old=1683 new=1821
[14:27:39] ✅ [CHANGE-DETECT] changed agents-alive.html — old=1683 new=1821
[14:27:39] ✅ [CHANGE-DETECT] changed agents-archi.html — old=1683 new=1821
[14:27:39] ✅ [CHANGE-DETECT] changed agents-final.html — old=1683 new=1821
[14:27:40] ✅ [CHANGE-DETECT] changed agents-fleet.html — old=1683 new=1821
[14:27:40] ✅ [CHANGE-DETECT] changed agents-goodjob.html — old=1683 new=1821
[14:27:41] ✅ [CHANGE-DETECT] changed agents-hd.html — old=1683 new=1821
[14:27:41] ✅ [CHANGE-DETECT] changed agents-hd2.html — old=1683 new=1821
[14:27:41] ✅ [CHANGE-DETECT] changed agents-hub.html — old=9259 new=1821
[14:27:42] ✅ [CHANGE-DETECT] changed agents-ia.html — old=1683 new=1821
[14:27:42] ✅ [CHANGE-DETECT] changed agents-iso3d.html — old=1683 new=1821
[14:27:43] ✅ [CHANGE-DETECT] new page agents-unified-registry.html — size=1821
[14:27:43] ✅ [CHANGE-DETECT] changed agents-valuechain.html — old=1683 new=1821
[14:27:43] ✅ [CHANGE-DETECT] changed ai-benchmark.html — old=1683 new=1821
[14:27:43] ✅ [CHANGE-DETECT] changed ai-hub.html — old=17398 new=21039
[14:27:44] ✅ [CHANGE-DETECT] changed all-screens-live.html — old=72 new=1821
[14:27:44] ✅ [CHANGE-DETECT] changed anthropic-hub.html — old=6227 new=1821
[14:27:44] ✅ [CHANGE-DETECT] changed api-key-hub.html — old=12517 new=16158
[14:27:45] ✅ [CHANGE-DETECT] changed apps.html — old=1683 new=1821
[14:27:45] ✅ [CHANGE-DETECT] changed architecture-live.html — old=32116 new=1821
[14:27:45] ✅ [CHANGE-DETECT] changed architecture-map.html — old=31488 new=1821
[14:27:46] ✅ [CHANGE-DETECT] changed architecture.html — old=51850 new=1821
[14:27:46] ✅ [CHANGE-DETECT] changed arsenal-login.html — old=6431 new=1821
[14:27:46] ✅ [CHANGE-DETECT] changed arsenal-offline.html — old=3064 new=6459
[14:27:47] ✅ [CHANGE-DETECT] new page automation-hub.html — size=1821
[14:27:47] ✅ [CHANGE-DETECT] changed avatar-picker.html — old=11373 new=1821
[14:27:48] ✅ [CHANGE-DETECT] new page azure-reregister.html — size=1821
[14:27:48] ✅ [CHANGE-DETECT] new page blade-actions.html — size=1821
[14:27:49] ✅ [CHANGE-DETECT] changed blade-ai.html — old=1683 new=1821
[14:27:49] ✅ [CHANGE-DETECT] changed blade-center.html — old=1683 new=1821
[14:27:49] ✅ [CHANGE-DETECT] new page blade-control.html — size=1821
[14:27:50] ✅ [CHANGE-DETECT] changed blade-hub.html — old=8868 new=12318
[14:27:50] ✅ [CHANGE-DETECT] changed blade-install.html — old=1683 new=1821
[14:27:50] ✅ [CHANGE-DETECT] changed booking.html — old=9404 new=12961
[14:27:50] ✅ [CHANGE-DETECT] changed bpmn-studio-NEW.html — old=6014 new=1821
[14:27:51] ✅ [CHANGE-DETECT] changed bpmn-studio-live.html — old=7435 new=1821
[14:27:51] ✅ [CHANGE-DETECT] changed brain-center-tenant.html — old=5110 new=1821
[14:27:51] ✅ [CHANGE-DETECT] new page candidate-detail.html — size=1821
[14:27:52] ✅ [CHANGE-DETECT] new page candidates-pool.html — size=1821
[14:27:52] ✅ [CHANGE-DETECT] new page caps-hub.html — size=8583
[14:27:52] ✅ [CHANGE-DETECT] changed cartographie-screens.html — old=258098 new=1821
[14:27:52] ✅ [CHANGE-DETECT] changed case-studies.html — old=13265 new=16851
[14:27:52] ✅ [CHANGE-DETECT] changed cgu.html — old=8701 new=12096
[14:27:53] ✅ [CHANGE-DETECT] changed claude-monitor.html — old=1683 new=1821
[14:27:53] ✅ [CHANGE-DETECT] changed claw-chat.html — old=1683 new=1821
[14:27:54] ✅ [CHANGE-DETECT] changed claw-code.html — old=1683 new=1821
[14:27:54] ✅ [CHANGE-DETECT] changed cloudflare-hub.html — old=15165 new=18806
[14:27:54] ✅ [CHANGE-DETECT] changed command-center.html — old=1683 new=1821
[14:27:55] ✅ [CHANGE-DETECT] new page consultants-list.html — size=1821
[14:27:55] ✅ [CHANGE-DETECT] new page contacts-segmentation-dashboard.html — size=1821
[14:27:55] ✅ [CHANGE-DETECT] new page crm-audit.html — size=1821
[14:27:56] ✅ [CHANGE-DETECT] new page crm-dashboard-live.html — size=1821
[14:27:56] ✅ [CHANGE-DETECT] new page crm-pipeline-live.html — size=1821
[14:27:56] ✅ [CHANGE-DETECT] changed crm.html — old=20460 new=25228
[14:27:56] ✅ [CHANGE-DETECT] changed cron-control.html — old=1683 new=1821
[14:27:57] ✅ [CHANGE-DETECT] changed crons-monitor.html — old=1683 new=1821
[14:27:57] ✅ [CHANGE-DETECT] changed cyber-monitor.html — old=1683 new=1821
[14:27:57] ✅ [CHANGE-DETECT] new page dashboards-hub.html — size=1821
[14:27:58] ✅ [CHANGE-DETECT] changed data-deletion.html — old=2589 new=5984
[14:27:58] ✅ [CHANGE-DETECT] new page database-dashboard-live.html — size=1821
[14:27:58] ✅ [CHANGE-DETECT] new page decision-gmail-o365.html — size=1821
[14:27:58] ✅ [CHANGE-DETECT] changed deepseek-hub.html — old=6405 new=9855
[14:27:58] ✅ [CHANGE-DETECT] changed deepseek.html — old=63142 new=67672
[14:27:59] ✅ [CHANGE-DETECT] changed deerflow-hub.html — old=4373 new=8014
[14:27:59] ✅ [CHANGE-DETECT] new page dg-command-center.html — size=34681
[14:27:59] ✅ [CHANGE-DETECT] changed director-center.html — old=1683 new=1821
[14:27:59] ✅ [CHANGE-DETECT] changed director-chat.html — old=1683 new=1821
[14:28:00] ✅ [CHANGE-DETECT] changed director.html — old=1683 new=1821
[14:28:00] ✅ [CHANGE-DETECT] changed dmaic-tracker-NEW.html — old=5626 new=1821
[14:28:00] ✅ [CHANGE-DETECT] changed dmaic-workbench.html — old=6798 new=1821
[14:28:00] ✅ [CHANGE-DETECT] changed docker-hub.html — old=4398 new=8039
[14:28:01] ✅ [CHANGE-DETECT] new page doctrine-53.html — size=1821
[14:28:01] ✅ [CHANGE-DETECT] new page dormant-dashboard-v2.html — size=1821
[14:28:02] ✅ [CHANGE-DETECT] new page dormant-dashboard.html — size=1821
[14:28:02] ✅ [CHANGE-DETECT] changed droid-terminal-hidden.html — old=1683 new=1821
[14:28:02] ✅ [CHANGE-DETECT] changed droid-terminal.html — old=107 new=1821
[14:28:02] ✅ [CHANGE-DETECT] changed ecosysteme-ia-maroc.html — old=11412 new=14807
[14:28:03] ✅ [CHANGE-DETECT] new page em-dashboard.html — size=1821
[14:28:03] ✅ [CHANGE-DETECT] changed email-hub.html — old=14982 new=18623
[14:28:03] ✅ [CHANGE-DETECT] new page enterprise-complete-v73.html — size=29606
[14:28:03] ✅ [CHANGE-DETECT] new page enterprise-complete.html — size=35207
[14:28:04] ✅ [CHANGE-DETECT] changed enterprise-management.html — old=1683 new=1821
[14:28:04] ✅ [CHANGE-DETECT] changed enterprise-model.html — old=176886 new=200606
[14:28:04] ✅ [CHANGE-DETECT] new page erp-gap-fill-offer.html — size=36827
[14:28:04] ✅ [CHANGE-DETECT] new page erp-launchpad.html — size=33933
[14:28:04] ✅ [CHANGE-DETECT] changed ethica-chatbot.html — old=9827 new=1821
[14:28:05] ✅ [CHANGE-DETECT] new page ethica-country.html — size=1821
[14:28:05] ✅ [CHANGE-DETECT] new page ethica-dashboard-live.html — size=1821
[14:28:05] ✅ [CHANGE-DETECT] new page ethica-drill.html — size=1821
[14:28:06] ✅ [CHANGE-DETECT] changed ethica-hcp-manager.html — old=1683 new=1821
[14:28:06] ✅ [CHANGE-DETECT] changed ethica-hub.html — old=16892 new=20435
[14:28:06] ✅ [CHANGE-DETECT] changed ethica-login.html — old=8595 new=1821
[14:28:06] ✅ [CHANGE-DETECT] changed ethica-monitor.html — old=1683 new=1821
[14:28:07] ✅ [CHANGE-DETECT] changed ethica-pipeline.html — old=1683 new=1821
[14:28:07] Scanning APIs...
[14:28:11] Scanning Docker...
[14:28:11] Checking S95...
[14:28:11] ✅ [S95-HEALTH] Sentinel reachable
[14:28:11] ✅ [S95-HEALTH] PMTA active
[14:28:12] ✅ [S95-HEALTH] KumoMTA active
[14:28:12] Checking S151...
[14:28:12] ✅ [S151-HEALTH] HTTP 200
[14:28:12] Checking Blade...
[14:28:12] ✅ [BLADE-HEALTH] heartbeat fresh — 0min ago, blade
[14:28:12] Checking Paperclip...
[14:28:12] ✅ [PAPERCLIP] service live (HTTP 200)
[14:28:12] Checking disk...
[14:28:12] ✅ [DISK] usage 78% — 78%
[14:28:12] 🔍 Changes detected: 102
[14:28:12] 📸 PHASE 2: Auto-testing pages...
[14:28:16] ✅ [PAGE-TEST] blade-ai.html OK — body=771, 0 JS errors
[14:28:20] ✅ [PAGE-TEST] crm.html OK — body=127, 0 JS errors
[14:28:25] ✅ [PAGE-TEST] agents-goodjob.html OK — body=52, 0 JS errors
[14:28:28] ✅ [PAGE-TEST] admin-saas.html OK — body=1435, 0 JS errors
[14:28:31] ✅ [PAGE-TEST] crons-monitor.html OK — body=153, 0 JS errors

File diff suppressed because one or more lines are too long

11
patch_security_fortress.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
PATH_F="/var/www/html/api/wevia-security-fortress.php"
# Check if already patched
if grep -q "V88 hardened" "$PATH_F"; then
echo "ALREADY"
exit 0
fi
# Need to use sudo if root-owned
sudo -n sh -c "chattr -i $PATH_F 2>/dev/null; sed -i '1a // V88 hardened\n@set_time_limit(30);\n@ini_set(\"memory_limit\", \"128M\");' $PATH_F; chattr +i $PATH_F 2>/dev/null"
php8.4 -l "$PATH_F" 2>&1 | tail -1
grep -c "V88" "$PATH_F"

31
scan_state.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/bash
echo "=== NR cache ==="
stat -c "cache_date: %y" /tmp/l99-honest-cache.json 2>/dev/null
AGE=$(($(date +%s) - $(stat -c %Y /tmp/l99-honest-cache.json 2>/dev/null || echo 0)))
echo "cache_age: ${AGE}s"
python3 -c "
import json
d=json.load(open('/tmp/l99-honest-cache.json'))
print(f'NR: {d[\"combined\"][\"pass\"]}/{d[\"combined\"][\"total\"]} · {d[\"pct\"]}% · {d[\"sigma\"]}')
print(f'ts: {d[\"ts\"]}')
" 2>/dev/null
echo ""
echo "=== Git ==="
cd /var/www/html && echo "dirty: $(git status --short | wc -l)"
cd /var/www/html && git log -1 --format="head: %h %s"
echo ""
echo "=== FPM ==="
ps aux | grep -c "php-fpm: pool"
echo ""
echo "=== V88 patches verify ==="
echo "auto-heal: $(grep -c 'V88' /var/www/html/api/wevia-auto-heal.php)"
echo "master-autoheal: $(grep -c 'V88' /var/www/html/api/wevia-master-autoheal.php)"
echo "searxng: $(grep -c 'V88' /var/www/html/api/searxng-proxy.php)"
echo "v83-dash-data: $(grep -c 'V88' /var/www/html/api/v83-business-kpi-dashboard-data.php)"
echo ""
echo "=== L99 cron ==="
crontab -l 2>/dev/null | grep -i l99 | head -3

BIN
screenshots/Admin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
screenshots/Archi3D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
screenshots/CRM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
screenshots/Console.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/DeerFlow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

BIN
screenshots/DirChat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/Director.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/Enterprise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
screenshots/Fleet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/Kuma.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
screenshots/L99Brain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
screenshots/Langfuse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
screenshots/Mattermost.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

BIN
screenshots/Meetings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/MiroFish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
screenshots/OpenClaw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/Paperclip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
screenshots/PaperclipPg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
screenshots/Plausible.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
screenshots/ValueStream.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/WEVADS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 231 KiB

BIN
screenshots/n8n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 KiB

After

Width:  |  Height:  |  Size: 776 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

After

Width:  |  Height:  |  Size: 649 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 KiB

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 90 KiB

97
selenium_business_test.py Normal file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""
V89 Selenium Business Scenario Test (headless chrome)
Scenarios testés:
1. WTP (weval-technology-platform.html) - page principale
2. WEVIA Master chat
3. CRM Bridge V68
4. Business KPI V83
5. Manifest endpoint
6. 15 Depts dashboard
"""
import sys, os, time, json, traceback
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
opts = Options()
opts.add_argument("--headless=new")
opts.add_argument("--no-sandbox")
opts.add_argument("--disable-dev-shm-usage")
opts.add_argument("--disable-gpu")
opts.add_argument("--window-size=1920,1080")
opts.add_argument("--ignore-certificate-errors")
opts.add_argument("--disable-web-security")
results = {"ts": time.strftime("%Y-%m-%dT%H:%M:%S"), "scenarios": [], "pass": 0, "fail": 0}
def run_scenario(name, url, expected_text=None, check_title=True, timeout=12):
"""Test a page: loads, title+body+screenshot + opt text match"""
driver = None
try:
driver = webdriver.Chrome(options=opts)
driver.set_page_load_timeout(timeout)
t0 = time.time()
driver.get(url)
load_time = round(time.time() - t0, 2)
title = driver.title
body = driver.find_element(By.TAG_NAME, "body").text[:300]
status = "PASS"
detail = {"title": title, "body_preview": body[:100], "load_time_s": load_time}
if expected_text and expected_text.lower() not in body.lower() and expected_text.lower() not in title.lower():
status = "WARN"
detail["missing_text"] = expected_text
# Screenshot
screenshot_path = f"/tmp/selenium_{name}.png"
driver.save_screenshot(screenshot_path)
detail["screenshot"] = screenshot_path
detail["screenshot_size"] = os.path.getsize(screenshot_path)
results["scenarios"].append({"name": name, "url": url, "status": status, **detail})
if status == "PASS": results["pass"] += 1
else: results["fail"] += 1
print(f" [{status}] {name:<30} load={load_time}s title='{title[:50]}'")
except Exception as e:
results["scenarios"].append({"name": name, "url": url, "status": "FAIL", "error": str(e)[:200]})
results["fail"] += 1
print(f" [FAIL] {name:<30} {str(e)[:100]}")
finally:
if driver: driver.quit()
print("=" * 70)
print("V89 SELENIUM BUSINESS SCENARIOS")
print("=" * 70)
scenarios = [
("wtp_main", "https://weval-consulting.com/weval-technology-platform.html", "WEVAL"),
("wevia_master", "https://weval-consulting.com/wevia-master.html", "WEVIA"),
("business_kpi", "https://weval-consulting.com/business-kpi-dashboard.php", "KPI"),
("crm_hub", "https://weval-consulting.com/crm.html", None),
("main_site", "https://weval-consulting.com/", "WEVAL"),
("manifest_api", "https://weval-consulting.com/api/weval-archi-manifest.php", "weval"),
("l99_honest", "https://weval-consulting.com/api/l99-honest.php", "6sigma"),
("depts_kpi", "https://weval-consulting.com/api/wevia-v64-departments-kpi.php", "departments"),
]
for name, url, expected in scenarios:
run_scenario(name, url, expected)
print()
print("=" * 70)
print(f"RESULTS: {results['pass']} PASS / {results['fail']} FAIL")
print("=" * 70)
# Save results
with open("/tmp/selenium_business_results.json", "w") as f:
json.dump(results, f, indent=2)
print(f"Saved: /tmp/selenium_business_results.json")
# Cleanup if ok
total = results["pass"] + results["fail"]
pct = round(100 * results["pass"] / total, 1) if total else 0
print(f"Pass rate: {pct}%")
sys.exit(0 if results["fail"] == 0 else 1)

21
tune_fpm.py Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env python3
path = "/etc/php/8.5/fpm/pool.d/www.conf"
with open(path, "rb") as f:
raw = f.read()
# Tune pm.* values - more aggressive spare servers to avoid "seems busy" warnings
replacements = [
(b"pm.max_children = 80", b"pm.max_children = 100"),
(b"pm.start_servers = 20", b"pm.start_servers = 30"),
(b"pm.min_spare_servers = 10", b"pm.min_spare_servers = 15"),
(b"pm.max_spare_servers = 30", b"pm.max_spare_servers = 40"),
]
for old, new in replacements:
# Only replace ACTIVE lines (not comments) - we know they're now deduped
if old in raw and b";" + old not in raw[:raw.find(old)+len(old)+1]:
raw = raw.replace(old, new, 1)
with open(path, "wb") as f:
f.write(raw)
print("tuned")

Binary file not shown.

Binary file not shown.

Binary file not shown.