diff --git a/api/wevia-gemini-ux-apply.sh b/api/wevia-gemini-ux-apply.sh index 00a9a553b..a2e69ed6d 100755 --- a/api/wevia-gemini-ux-apply.sh +++ b/api/wevia-gemini-ux-apply.sh @@ -36,7 +36,7 @@ python3 /var/www/html/api/wgux-parse.py "$OUT/gemini-raw.json" "$OUT/plan.json" # 5) Apply if mode=apply APPLIED="false" if [ "$MODE" = "apply" ] && [ -f "$OUT/plan.json" ]; then - python3 /var/www/html/api/wgux-apply.py "$OUT/plan.json" "$TARGET" "$TS" > "$OUT/apply.log" 2>&1 + sudo python3 /var/www/html/api/wgux-apply.py "$OUT/plan.json" "$TARGET" "$TS" > "$OUT/apply.log" 2>&1 if grep -q "APPLIED" "$OUT/apply.log"; then APPLIED="true" fi diff --git a/api/wgux-apply.py b/api/wgux-apply.py index 4732c90d3..117781581 100755 --- a/api/wgux-apply.py +++ b/api/wgux-apply.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Apply Gemini CSS patch with GOLD backup + idempotent marker""" +"""Apply Gemini CSS patch v2 - sudo chattr + verify post-apply""" import sys, json, os, shutil, subprocess, time plan_path = sys.argv[1] @@ -24,8 +24,11 @@ if not css or not safe: marker_start = f"" marker_end = "" -with open(target) as f: - html = f.read() +try: + with open(target) as f: html = f.read() +except PermissionError: + print(f"PERM_READ_FAIL {target}") + sys.exit(1) if 'DOCTRINE-201-GEMINI-APPLY' in html: print("ALREADY") @@ -40,19 +43,46 @@ page = os.path.basename(target).replace('.html', '') backup = f"/var/www/html/vault-gold/opus/{page}.html.doctrine201-apply-{ts}.bak" os.makedirs('/var/www/html/vault-gold/opus', exist_ok=True) shutil.copyfile(target, backup) +size_before = os.path.getsize(target) -# Clean CSS - ensure starts with ' full = f"\n{marker_start}\n{css}\n{marker_end}\n" new_html = html.replace('', full + '', 1) -# Unlock / write / relock -subprocess.run(['chattr', '-i', target], capture_output=True) -with open(target, 'w') as f: - f.write(new_html) -subprocess.run(['chattr', '+i', target], capture_output=True) +# Unlock with SUDO (critical fix) +r1 = subprocess.run(['sudo', 'chattr', '-i', target], capture_output=True, text=True) +unlocked = (r1.returncode == 0) -size = os.path.getsize(target) -print(f"APPLIED size:{size} backup:{backup}") +# Write via sudo tee if direct write fails +try: + with open(target, 'w') as f: + f.write(new_html) + write_ok = True +except PermissionError: + # Fallback via sudo tee + p = subprocess.run(['sudo', 'tee', target], input=new_html, capture_output=True, text=True) + write_ok = (p.returncode == 0) + +# Relock with SUDO +r2 = subprocess.run(['sudo', 'chattr', '+i', target], capture_output=True, text=True) + +# VERIFY post-apply +size_after = os.path.getsize(target) +with open(target) as f: final_html = f.read() +marker_present = 'DOCTRINE-201-GEMINI-APPLY' in final_html + +if marker_present and size_after > size_before: + print(f"APPLIED size_before:{size_before} size_after:{size_after} delta:+{size_after - size_before} backup:{backup}") + sys.exit(0) +else: + print(f"APPLY_FAIL marker:{marker_present} size_before:{size_before} size_after:{size_after} unlocked:{unlocked} write_ok:{write_ok}") + # Restore from backup if corrupted + if not marker_present and size_after != size_before: + subprocess.run(['sudo', 'chattr', '-i', target], capture_output=True) + shutil.copyfile(backup, target) + subprocess.run(['sudo', 'chattr', '+i', target], capture_output=True) + print(f"RESTORED_FROM_BACKUP") + sys.exit(1) diff --git a/api/wgux-parse.py b/api/wgux-parse.py index b8d76e420..a5f453d81 100755 --- a/api/wgux-parse.py +++ b/api/wgux-parse.py @@ -29,8 +29,12 @@ try: # Try to extract css field directly css_m = re.search(r'"css"\s*:\s*"( +
diff --git a/products/auditai.html b/products/auditai.html index 445dfebfb..b63bdb611 100644 --- a/products/auditai.html +++ b/products/auditai.html @@ -86,6 +86,354 @@ input,select,textarea{background:#0b0d14!important;color:#e2e8f0!important;borde @media (max-width:768px){#weval-bot-widget{bottom:100px !important;right:16px !important;z-index:10001 !important}#weval-bot-btn{width:48px !important;height:48px !important}#weval-bot-btn svg{width:22px !important;height:22px !important}#footer_banner,.footer-banner,[class*="footer-bandeau"]{z-index:9990 !important}} + + + +Auditez la qualité de vos bases de données en temps réel. Scoring, détection d'anomalies, nettoyage et conformité RGPD automatisés.
500 MW de GPU Naver-NVIDIA, Mistral AI en partenariat national, Digital Morocco 2030 — le Maroc attire les géants de l'IA. WEVAL Consulting est positionné au coeur de cette transformation.
Depuis Casablanca, nous déploiement des solutions IA sur infrastructure GPU dediee. Voici ce qui nous differencie :
+Depuis Casablanca, nous déployons des solutions IA sur infrastructure GPU dediee. Voici ce qui nous differencie :
Obtenez un diagnostic gratuit de votre readiness IA souveraine. 15 minutes, zero engagement.
- Demander un diagnostic gratuit → + Demander un diagnostic gratuit →