2026-08-18 — يومية
🔮 إصلاح foresight/مجلس النخبة — تعليق EXIT=124 (نُفّذ + مُختبَر حيّاً E2E، صفر سلبيات)
البلاغ (د. وائل صوتاً): foresight.py تجاوز مهلة (280s) EXIT=124 مع أنه ينجح دائماً — لماذا اليوم؟ ادرس الجذر بعمق + عالجه بخطة نقدية متعددة المستويات + never-stop (صفر سلبيات، لا شلل، أي عائق نتجاوزه بـ bypass/fallback فوراً).
الجذر الحقيقي (مُثبَت بالبيانات لا التخمين — DBT):
مزدوج، اكتُشف بالفحص الحيّ للكود + السجل: 1._run_parallel (elite-council) بلا سقف زمني كلّي: as_completed() بلا timeout= → ينتظر أبطأ نموذج بلا حدّ + retry يضاعف. بعد رفع Grok 4.6 (أبطأ من 4.5) + opus-5 في الأدوار، زحفت مدة المجلس من ~420s إلى ~1050s (سجل الكرون: 08-13=1125s، 08-16=1051s، 08-18=EXIT124).
2. القاضي (SYNTHESIZER route_call) بلا مهلة + مهلة الكرون الخارجية 280s < العمل الفعلي (خرق قاعدتنا: الداخلية أكبر من الخارجية).
3. 🔴 الجذر الأعمق (اكتُشف بالاختبار الحيّ، لا يُنسى): ThreadPoolExecutor — حتى مع shutdown(wait=False) وثريدات daemon — يسجّل atexit hook (_python_exit) يجمع (join) كل ثريدات المجمع عند خروج المفسّر بغضّ النظر عن daemon → فحتى لو حسبنا النتيجة في 3s، العملية تعلق عند الخروج حتى ينتهي الثريد العالق = نفس EXIT=124 بالضبط. الحل: ثريدات daemon خام يدوية + queue (لا ThreadPoolExecutor للاستدعاءات القابلة للتعليق) + os._exit(0) بعد طباعة التقرير (تجاوز atexit join نهائياً).الحل المُطبَّق (6 مستويات، backward-compatible 100%):
HTTP_TIMEOUT180→90 (كافٍ، النماذج تجيب 8-40s)._run_parallel(tasks, deadline=None)— سقف كلّي اختياري؛deadline=None= سلوك قديم تماماً (صفر كسر للمستدعين: podcast.py · collective_council.py · economic_council_podcast.py). ثريدات daemon خام + queue (لا ThreadPoolExecutor).- تقسيم الميزانية: الأدوار 55% · المناظرة 20% · القاضي = الباقي بحدّ أدنى 70s (فلا يُجوّع القاضي — كان جذر [FAILED] judge الحيّ).
_call_with_deadlineللقاضي (سقف كلّي).- foresight.py:
run_council(deadline=300)+council_failedيشمل_failed(conclusion)+ fallback نهائي (Gemini 3.1 Pro ثم opus-4-8 ثم اعتذار صادق — لا صفر مخرج أبداً) +os._exit(0)بعد الطباعة. - الكرون
564b6faa:timeoutSeconds: 720(هامش مزدوج فوق ~237s الحقيقية).
الإثبات الحيّ E2E (لا ادّعاء):
- منطقي معزول: legacy no-deadline ✅ · deadline يُسقط النموذج العالق ويُبقي السريع + خروج نظيف EXIT=0 ✅ · retry budget ✅ · judge deadline يُقصّ بلا تعليق ✅.
- حيّ حقيقي:
run_council5 نماذج + deadline → 130.5s، error=None، 5 perspectives، conclusion 4718، EXIT=0 ✅. - foresight.py كامل غير مُخزَّن (5 نماذج فعلية):
PYEXIT=0 ELAPSED=237s report=4 timeouts=0 size=10827✅. - backward-compat: 6 أدوار + conclusion للمستدعين القدامى ✅ · 3 مستدعين آخرين يُحلَّلون نظيفين ✅.
- verify_agreements.sh = EXIT 0 (صفر regression) ✅.
دروس تقنية دائمة (لا تُنسى):
ThreadPoolExecutorلا يُترك بثريد عالق أبداً (atexit join يجمع الكل). لأي استدعاء قابل للتعليق مع سقف زمني: ثريدات daemon خام + queue، ثمos._exit(0)لتجاوز atexit.pgrep -f/ps|grep foresight.pyself-match تكرّر (حكم «RUNNING» كاذب على grep نفسي). الحكم الصحيح:awk '/python3.foresight\.py/ && !/awk/'.- backgrounded
( ... ) &subshells تُقتل عند انتهاء exec session قبل كتابة سطر meta الأخير → «no PYEXIT» = artifact الاختبار لا bug الكود. الحسم = تشغيل synchronous (foreground). - stdout مُوجَّه لملف = block-buffered → التقرير لا يظهر حتى نهاية البرنامج (استخدم
-u).
النسخ الاحتياطية (rollback فوري):
skills/elite-council/council.py.bak.foresight_fix_20260818_100319 · skills/foresight-engine/foresight.py.bak.foresight_fix_20260818_100319.ملاحظة تنظيف مؤجّلة (غير حرجة):
council_health_guard.sh يفحص Grok-4.5 بينما المجلس صار Grok-4.6 (كلاهما حيّ HTTP 200 — تجميلي).---
بنود النشرة التقنية (مفحوصة — الحالة)
- Gemini 3.7 Flash: موضعه صحيح (fallback فوق 3.6) + حيّ. فجوة = توثيق ناقص (CAPABILITIES/ARSENAL/TOOLS) — للتوثيق.
- Sheets Canvas: ميزة Gemini رسمية — نص capability جاهز (عبر Browser Pro الموثّق) لسير عمل P6/takeoff/tenders/financial.
- GPT-5.6 Sol: مكانه صحيح (cross-provider #1) + حيّ. ultrafast = tier سرعة Cerebras أغلى ~5× بنفس الجودة → لا نضيفه (Best-Value؛ الجودة أولاً). watchlist.
- MCP: mcporter 0.13.7 آخر إصدار · متوافق Cloudflare/MCP v2 stateless · 16/17 healthy · ruflo = عطل upstream عند الناشر (لا يمسّ workflow).
🛡️ مشروع التحصين الشامل — تعميم never-stop على كل الترسانة (نُفّذ + مُختبَر E2E، صفر سلبيات)
السياق: بعد إصلاح foresight/council (EXIT=124) صباح اليوم، أوصيتُ بجلسة جديدة مخصّصة لتعميم الحماية على كل مواضع التفرّع المتوازي. د. وائل أمر: بتركيز، بلا تكديس، نقد 5 مستويات، اختبار عملي مليون بالمئة قبل التثبيت، صفر سلبيات.
الجرد القاطع (بالأرقام من الكود لا الذاكرة):
22 ملفاً من ملفاتنا تستخدمThreadPoolExecutor/as_completed (استُبعدت مكتبات venv — خارج النطاق).تصنيف DBT (بقراءة الكود الفعلي):
- مجموعة A محصّنة سلفاً (لم تُلمَس): council.py (أُصلح صباحاً) · multi_flagship_verify.py (
wait(timeout=100)+cancel) · academic_dean.py (timeout=240+.result(timeout=200)) · liberation_router.py (as_completed timeout=170). - مجموعة B خطر حقيقي (9 ملفات، عولجت): smart-code-router/route.py · multi-model-consensus/consensus.py · scripts/elite_council.py · synergy-war-room/war_room.py · academic-dean/code_router.py · academic-dean/media_router.py · web-reach/academic_fetch.py · document-ocr-arsenal/ocr_batch.py · scripts/council_uncensored.py.
- مجموعة C محلي منخفض الخطر: entertainment-hub · ask-rag · oasis (لم تُلمَس هذه الجولة — محلية I/O).
الوحدة الموحّدة الجديدة: scripts/lib/never_stop.py
مستخلَصة حرفياً من نمط council.py المُثبَت (ثريدات daemon خام + queue + deadline، لا ThreadPoolExecutor → لا atexit-join hang = جذر EXIT=124). دالتان: run_parallel_capped(tasks, deadline=None, retry_failed=False, on_result=None) + call_capped(fn, budget, default). صفر تبعيات (stdlib). selftest 10/10.التطبيق (9 ملفات، backward-compatible 100%):
كل ملف: نسخة احتياطية.bak.nstop_20260818_ → استبدال block التفرّع بـ run_parallel_capped مع deadline مُعايَر → compile OK.
deadlines مُعايَرة (نقد المستوى 4 أمسك بها): route/consensus=240 · elite_council/war_room=200 · council_uncensored=210 · academic_fetch=60 · ocr=max(300, 90×n/workers) · code_router=960 (سلسلة 3 طبقات×300s — كان 300 خطأً يقطع تصعيداً مشروعاً) · media_router video=1800/image=600 (سلسلة فيديو 6-9 طبقات×300s). القاعدة: السقف أكبر من الزمن الفعلي المشروع → يمنع التعليق فقط، لا يقطع عملاً صحيحاً.الإثبات الحيّ E2E (لا ادّعاء):
never_stop.py --selftest= 10/10 + EXIT=0 (مهمة نوم 10s لم تُعلّق العملية).- harness
/tmp/nstop_e2e.pyعلى الدوال الحقيقية (مهام نوم 20s متعددة) = 8/8 + EXIT=0 + WALL=25s (academic_fetch.search_all اختُبر بمصدر عالق فعلي ودمج الباقي). - verify_agreements.sh = EXIT 0 (صفر regression، 72 قسم + كل الحرّاس سليمة).
دروس تقنية دائمة:
- جذر EXIT=124 = atexit-join لـ ThreadPoolExecutor (
_python_exitيجمع كل ثريدات المجمع بغضّ النظر عن daemon). الحل الموحّد: ثريدات daemon خام + queue (never_stop.py). - معايرة deadline خط أحمر: يجب أن تكون أكبر من الزمن الفعلي المشروع لأطول سلسلة متسلسلة، وإلا تقطع never-stop.
- النسخ الاحتياطية: كل ملف
.bak.nstop_20260818_*(rollback فوري).
🛡️ الحارس الوقائي + توسيع التحصين — الجولة النهائية (نُفّذ + مُختبَر E2E، صفر سلبيات)
طلب د. وائل: ابنِ الحارس الإضافي، انتقده 4-5 مستويات لصفر سلبيات، اختبره عملياً، ثبّته، ثم أعد تدقيق كل ما بُني اليوم بأسوأ الاحتمالات.
الحارس الجديد: scripts/guards/nstop_coverage_guard.sh
- READ-ONLY تماماً (grep فقط، صفر كتابة/تشغيل/حذف). يكشف أي ملف بايثون من ملفاتنا فيه تفرّع متوازٍ (ThreadPoolExecutor + as_completed/.result/ex.map) بلا سقف زمني كلّي ولا run_parallel_capped.
- allowlist لمجموعة A المحصّنة سلفاً (council/multi_flagship/academic_dean/liberation_router). exit 2 = انتباه (لا يكسر keepalive). selftest 4/4.
🔴 قيمة الحارس أُثبتت فوراً — كشف نقصاً في تصنيفي:
تشغيله الحيّ الأول كشف 7 ملفات ظننتُها «محلية منخفضة الخطر» وهي فعلاً تفرّع شبكي بلا سقف:app.py (5 ex.map) · build_cats.py · indexer.py · epg.py · unified_search.py · podcast.py (LLM/TTS) · oasis_profile_generator.py (MiroFish). عالجتُها كلها بـ run_parallel_capped (backward-compatible + نسخ احتياطية).🔴 نقد الحارس نفسه أمسك ببق false-negative فيه:
الحارس كان يخلطproc.wait(timeout=5) (subprocess) بـ futures.wait(timeout=) فيُبرّئ app.py خطأً. أصلحتُه (تمييز concurrent.futures.wait عن Popen.wait) → صار يكشف app.py صحيحاً.النطاق النهائي الكامل: 19 ملفاً + الحارس + الوحدة
- الوحدة
scripts/lib/never_stop.py(selftest 10/10) - 9 ملفات مجموعة B + 2 ask-rag + 7 (app.py + entertainment×4 + podcast + oasis) = 18 مستهلكاً
- الحارس
nstop_coverage_guard.sh(مثبّت في daemons_keepalive كل 6h، تنبيه admin فقط).
الإثبات النهائي (كله حيّ):
- never_stop selftest = 10/10 EXIT=0 · guard selftest = 4/4 · guard live = نظيف (3 ملف، الباقي allowlist).
- core9 E2E = 8/8 · newfiles E2E = 5/5 (كل الأنماط: .map/as_completed/.result/tuple).
- compile 19 ملف = ✅ · keepalive syntax = ✅ · verify_agreements = EXIT 0 (صفر regression).
- نسخة احتياطية لكل ملف معدّل (rollback فوري) + keepalive.
دروس دائمة:
- الحارس الوقائي يجب أن يميّز أنماطاً متشابهة نصّياً (proc.wait ≠ futures.wait) وإلا false-negative.
- تصنيف «محلي» خطأ شائع: أي fan-out فيه urlopen/شبكة = خطر EXIT=124 مهما بدا «محلياً». الحكم بالكود لا بالاسم.
- entertainment-hub ليست محلية بحتة (EPG/ping/warm = شبكة IPTV).