04:43 — Entertainment Hub: Browse-by-category + real 'added' sort
- طلب د. وائل: sort من الأحدث (أضيف حديثاً) + تصفح حسب الفئة بدون اسم (كل الأفلام/المسلسلات/القنوات في فئة عبر كل الاشتراكات) ثم ترتيب.
- indexer.py: أضفت عمود added (vod/live=added, series=last_modified/releaseDate) + فهارس idx_added/idx_cat. reindex 1.155M عنصر في 40s، 99.99% لها added>0.
- catalog_search.py: search(sort=) + browse(tag,kind,sort,limit,offset) + browse_facets(kind). app.py: /api/catalog/browse + /api/catalog/browse-facets + sort في /search.
- Frontend index.html: تبويب 'تصفح حسب الفئة' + kind toggle (أفلام+مسلسلات/أفلام/مسلسلات/قنوات) + chips فئات من facets + server-sort (أضيف حديثاً/الأقدم/أبجدي/تقييم) + خيار 'أضيف حديثاً' في بحث الاسم (g.added=max عبر المصادر).
- PERF FIX: _xt_find كان يقرأ iptv_subscriptions.json من القرص لكل عنصر → browse 3000 عنصر=18.6s. أضفت _SUBS_CACHE (TTL 60s + byname dict) → 2.0s (9x). يفيد كل التطبيق.
- E2E Playwright (chromium نظامي): browse tab+45 chips+kind bar+60 cards+sort dropdown+back button ✅. search added-sort: options فيها added:أضيف حديثاً + __groups مرتبة added DESC ✅. tofu □ في الاختبار = غياب خط emoji على السيرفر فقط (يظهر سليم على S24).
- اختبارات محفوظة: projects/entertainment-hub/_e2e_browse.mjs + _e2e_final2.mjs.
04:53 — Browse multi-dimension COMBINE (AND) enhancement
- طلب د. وائل: دمج فئة+لغة+جمهور (رعب عربي، فكاهي عربي، فكاهي صغار، مسرحيات) والبدء من التصنيف ثم التضييق.
- catalog_search.browse(): tag صار CSV → AND عبر كل الاشتراكات. browse_facets(kind,sel): counts مُنقّحة حسب المختار (تُظهر فقط ما يمكن دمجه فعلاً — صفر dead-ends).
- Frontend: تبويب تصفّح أُعيد بناؤه multi-select عبر 3 محاور (النوع/اللغة والمنطقة/الجمهور) + selected-combo bar + مسح + server-sort. renderGroupedSearch أضيف opts.bare (يخفي chips/tools الداخلية للتصفّح).
- حقيقة البيانات: المزوّدون يصنّفون العربي بالمنطقة/النوع (كلاسيك/خليجي/مسرحيات/رمضان) لا بالنوع الدرامي غالباً → «رعب عربي»≈0 لكن «فكاهي عربي»=106، «مسرحيات» تحت عربي=1733. الـ chips تظهر فقط المتاح فعلياً (شفاف).
- E2E Playwright: عربي+كوميدي=106 عنوان، 60 cards، selected-combo bar يظهر، صفر أخطاء. dim rows الثلاثة تظهر في الحالة الابتدائية.
- (الحقيقة: الصور من السيرفر headless بلا خط emoji → □؛ يظهر سليم على S24).
05:05 — Browse: recency windows (أضيف حديثاً) + 🆕 badge
- طلب د. وائل: 'أضيف حديثاً' كنقطة انطلاق (كل الاشتراكات، كل الأنواع) + نوافذ زمنية (أسبوع/شهر/3/6 أشهر/سنة/سنتين) تُدمج مع باقي الفلاتر + بحث على أساس الأحدثية.
- backend: browse()+browse_facets() أضيف param since (unix ts) → WHERE i.added>=since (يستفيد idx_added). endpoints تمرّر since.
- frontend: صف 'الأحدثية' في تصفّح (كل الأوقات/أسبوع/شهر/3/6 أشهر/سنة/سنتان) + setBrowseWindow + since في fetch + شارة 🆕 جديد على البطاقات المضافة خلال 7 أيام.
- E2E: window row يظهر، شهر=13370، 🆕 يظهر، شهر+أكشن=73، صفر أخطاء.
- تأكيد معماري: cron 'Entertainment Hub — Catalog Reindex (24h)' (a52c22e6) مفعّل status ok → التصنيف الكامل (cats + added) يُعاد بناؤه كل 24h = رؤية د. وائل 'صنّف كله مرة/يوم في DB' مطبّقة سلفاً.
- معلّق (اقتراح): تصنيف 'غير مصنف' باستنتاج من الاسم (title-keyword inference) داخل build_cats + بحث مدمج اسم+فئة.
05:35 — Netflix/Disney answer + ready presets
- Netflix/Disney/Shahid: كلها IPTV فقط (13 sub). المحتوى موجود (نتفلكس 37538 + ديزني 10110). رفضت credentials رسمية (DRM يمنع التشغيل + أمان). TMDB discovery layer اختياري (مؤجّل، د. وائل مال لـ خلاص).
- رقاقات جاهزة (10 presets) في تصفّح: أحدث أفلام/مسلسلات (شهر)، أكشن أجنبي، كوميديا عربي، رعب أجنبي، عائلي، أطفال كرتون، مسرحيات، نتفلكس، أعلى تقييماً. applyPreset يطبّق kind+sel+window+sort دفعة.
- E2E: preset bar يظهر، كوميديا عربي=106، أحدث أفلام(vod 30d)=8174، صفر أخطاء.
- متبقٍ من الباتش: (1) بحث مدمج اسم+فئة، (2) مُصنِّف 'غير المصنّف' في build_cats اليومي.
05:53 — Batch complete: combined search + classifier upgrade
- بحث مدمج: browse() أضيف q param (FTS join مع فلاتر الفئة/اللغة/النافذة). frontend: صندوق بحث 'ابحث بالاسم داخل الفلاتر' + زر مسح + العنوان يعرض «الاستعلام». اختبار: batman داخل action=86، صفر أخطاء.
- مُصنِّف 'غير المصنّف' (category-level، أعلى ROI): genres.py — strip tatweel + توسيع foreign لكل لغات العالم (DE/IT/ES/PT/FR/RU/GR/IR/AL/Nordic...) + مترجم/مدبلج/multi-sub + regex رموز لغة ثنائية. النتيجة: untagged vod 42%→8%، series 31%→10%، live 66%→44%؛ foreign 265K→742K.
- reindex 51s (1.155M) طبّق التصنيف الجديد؛ يتكرر يومياً عبر cron a52c22e6.
- regression browse PASS (60 cards/61 chips). public tunnel يخدم الميزات.
- الباتش الكامل المسلّم: real added-sort + browse-by-category + multi-dimension combine + recency windows + 🆕 badge + ready presets + combined name search + classifier upgrade. كله مختبَر E2E Playwright.
06:36 — Final batch: live search + saved filters + production-year + live classifier + daily digest
- بحث مباشر أثناء الكتابة في التصفّح (debounce 400ms + إبقاء التركيز). حفظ التوليفة كفلتر (localStorage) + تطبيق/حذف.
- سنة الإنتاج: عمود year في items (parse من releaseDate/(YYYY)/آخر سنة صالحة، cap سنة+1 لمنع 2099). browse: فلتر ymin/ymax + ترتيب 'الأحدث إنتاجاً' + صف سنوات (2024+/2020+/2015+/كلاسيك).
- مُصنِّف القنوات الحية + لغات العالم: genres.py وسّع foreign (USA/UK/دول+ESPN/DAZN/PPV→sports، radio→music، news→programs). النتيجة النهائية: untagged vod 42→7%، series 31→7%، live 66→13%. live __other: 117K→22.5K.
- نشرة يومية 09:00 الكويت (cron dace6ac0): daily_new_digest.py يحسب مضاف آخر 24h (إجمالي/أفلام/مسلسلات/قنوات + أبرز الفئات + عيّنات) ويرسلها ذاتياً لتيليجرام (curl bot token، delivery none، haiku). اختُبر force-run: ok، أُرسلت.
- reindex النهائي طبّق year+classifier؛ يتكرر يومياً (cron a52c22e6).
- كل الميزات مختبرة E2E/HTTP. الملف مكتمل.
جلسة 2026-07-06 (صباحاً-ظهراً) — 3 محاور + تنظيف + دروس
النشرة التقنية
- LongCat 2.0 (Meituan، 1.6T MoE مفتوح): فُحص حيّاً. أضعف من Opus 4.8 وOpus 4.7 وحتى GLM-5.2 (مفتوحنا) في كل مقياس كود (SWE-Pro 59.5 vs Opus4.8=69.2؛ Terminal-Bench 70.8 vs GLM-5.2=81.0). غير متاح على OpenRouter (340 موديل، صفر تطابق؛ نداء = 400 not valid). المسار الوحيد = مفتاح منصّة LongCat مدفوع لموديل أضعف مما عندنا. القرار (د. وائل): Watchlist فقط، لا إضافة (يخالف M-025/Best-Value). يُراقب في weekly_arsenal_audit؛ إن عاد لـ OpenRouter مجاناً يُختبر كـ fallback كود مفتوح تحت GLM-5.2.
- Hermes = anthropic/claude-sonnet-5 (via OpenRouter) — مؤكّد حيّاً من
hermes config show. غُيّر 2026-07-05 من opus-4.8. د. وائل كان محقاً، ذاكرتي (TOOLS.md) كانت stale — صُحّحت. المنطق: عمليات Hermes المتتالية أوفر على Sonnet 5، Opus 4.8 يبقى القائد/المُخرج النهائي على OpenClaw.
- X Hosted MCP: مُقفل (قرار 07-01) — نكتفي بـ x_search + تحقّق مزدوج، لا اشتراك.
الاستثمار (invest-auto) — توسعة كبرى
- funds_catalog.py = مصدر حقيقة واحد لكل 28 صندوق Kuveyt Türk Portföy katılım (حلال)، اكتُشفت حيّاً من TEFAS list endpoint
/api/funds/fonGetiriBazliBilgiGetir (1033 صندوق كلي، 28 KT). fetch_data + forecast + generate_pages تستهلكه.
- صفحة الصناديق: 8 → 28 صندوقاً، مصنّفة 6 فئات (income/mixed/equity/sector/gold/fx)، ⭐ الأفضل بكل فئة + وسم معفى 0%.
- محرّك التوزيع الديناميكي (dynamic_allocation): صفحة الوديعة/التوزيع صار التوزيع نفسه يختار أفضل صندوق بكل فئة حيّاً (KME بدل KLU، KCV ظهر، KPC/KNJ) + إشارات استراتيجية (احتفاظ/تجميع DCA/تقليم) من الزخم + forecast 90 يوم. التوصيات ديناميكية (dyn_fund_recs).
- fetch_data hardening: أضيف retry×4 backoff + last-known-good carry-forward (سبب فشل صباح 07-06 = انقطاع TEFAS مؤقت + محاولة واحدة صامتة). الآن 28/28 حيّ.
- توقيع صُحّح: «OpenClaw» → «الترسانة» في التوصيات (قاعدة الهوية).
- اكتشافات لافتة: KGM فضة 88%، KCV متعدد أصول 57.5% بمخاطرة 2/7 (أفضل عائد/مخاطرة)، KME 48.3% مخاطرة 1/7 (يتفوق على KLU)، KTS أسهم معفاة زخم 6.9%.
Open WebUI (local.drwaelalkishawi.com)
- ترقية 0.9.6 → 0.10.2، ثم تثبيت compose على
:v0.10.2 (بدل :main) للاستقرار. healthy + public 200. البيانات على volume (890M) + نسخة DB احتياطية. الترقية المستقبلية يدوية بعد فحصي (weekly audit).
تنظيف تخزين (85% → 80%، ~8G)
- أُزيلت صورة Open WebUI 0.9.6 dangling (6.63G) + openclaw-tmp (2.4G) + compile-cache + /tmp قديم. لم يُحذف: camoufox (1.4G) + صور docker on-demand (Blender ~5.7G) — لها أثر (إعادة تنزيل).
دروس دائمة (السجل)
- M-077: لا نسبة فشل لسبب قبل قراءة السجل الخام (نسبتُ فشل 11:19 لـ M-048 خطأً؛ السجل أثبت M-063 replay_invalid/thinking-signature عابر).
- M-078: لا exec ينتهي بأمر exit≠0 حميد (grep -c بصفر تطابق سرّب إشعار أحمر). اختم بـ
|| true.
- M-079: لا process kill لفحص حميد (سرّب "Process failed"). استخدم
timeout N ... || true.
بندان مفتوحان (لم يُنفّذا — بانتظار قرار د. وائل، بعد /new)
1) Obsidian vault متجمّد عند 10 يونيو
- الدليل: vault MISTAKES_LEDGER=145K (Jun10) vs live 206K؛ الذاكرة-اليومية بالـvault تقف 2026-05-27.
- السبب: Syncthing ينشر الـvault للأجهزة، لكن لا شيء يُحدّث محتوى الـvault من الـworkspace الحيّ. الـvault لقطة واحدة قديمة.
- الحل المقترح: cron يومي يزامن (workspace reference + memory/.md → vault) ثم Syncthing/LiveSync ينشر. ⚠️ قبل التنفيذ: تأكيد أيّ آلية أساسية (CouchDB LiveSync أم Syncthing) لتجنّب تعارض على أجهزته. المسار: /data/.openclaw/workspace/obsidian/00-الترسانة/{الذاكرة-اليومية,القواعد-الذهبية,المرجعية}.
2) n8n.drwaelalkishawi.com — Google Safe Browsing phishing flag
- الصورة أكّدت: Chrome "Dangerous site" + "Safe Browsing recently found phishing". الخادم يرجع 200 (سليم). فقط n8n مؤشَّر (portal/invest لا).
- السبب المرجّح: واجهة تسجيل دخول n8n العامة يصنّفها مُصنّف جوجل كتصيّد (شائع لـn8n self-hosted مكشوف).
- الحل (بلا كسر الربط): (أ) Cloudflare Access OTP على واجهة/دخول n8n فقط مع إبقاء /webhook/ و /mcp/wael-arsenal/sse مفتوحة (توكناتها الخاصة) — بوت جوجل لا يصل صفحة الدخول → التحذير يزول. (ب) Google Search Console → Security Issues → Request Review. ⚠️ يمسّ ربط MCP wael-arsenal — التنفيذ بتحقّق حيّ خطوة-خطوة أن /mcp/ يبقى حياً.
✅ Obsidian sync — حُلّ (2026-07-06 ~14:05)
- السبب المؤكّد: Syncthing عنده مجلدان (obsidian-vault → /workspace/obsidian ، openclaw-vault → /workspace كامل). مجلد obsidian-vault/00-الترسانة كان لقطة واحدة من 10 يونيو، لا شيء يُحدّث محتواه من الـworkspace الحيّ. connected devices=0 وقتها (اللابتوب/الموبايل offline، Syncthing ينشر عند اتصالهم).
- الحل المنفّذ:
scripts/sync_obsidian_vault.sh (one-way workspace→vault، idempotent): memory/.md → الذاكرة-اليومية/ · 16 مرجعية → المرجعية/ · matrices+GOLDEN_PROMPT → القواعد-الذهبية/ · تحديث 00-الفهرس بطابع زمني. + أُضيف لـ daemons_keepalive (throttle 24h، صفر LLM، نمط R2).
- التحقق: 107 ملف زُومنت · آخر يومية 06-10→07-06 · MISTAKES_LEDGER 145K→206K مطابق · Syncthing rescan 200 · localFiles 44→141 · needFiles 0. الـvault صار منصة recovery حيّة محدّثة تُنشر لكل الأجهزة عند اتصالها.
- Syncthing: GUI 0.0.0.0:8384، folders: obsidian-vault + openclaw-vault. API key في config.xml.
n8n — قرار د. وائل: يُترك كما هو (تحذير Google Safe Browsing فقط، سيرفرنا سليم، لا يؤثر على العمل ولا الوصول). مُغلق.
M-077 — Syncthing hardening (Phase A + B) — 2026-07-06 ~16:40 الكويت
السياق: د. وائل رصد Obsidian sync متوقّف عند 10 يونيو على الأجهزة + sync.drwaelalkishawi.com يعطي 502 دورياً.
التشخيص (أدلّة حيّة):
- المزامنة = Syncthing (لا CouchDB — النص القديم مضلّل). sync.drwael... → sync-proxy(nginx) → syncthing:8384.
- 502 = Syncthing عملية عارية داخل حاوية openclaw، تموت ~مرة/يوم، حارس keepalive بـ pgrep فقط (كل 5د) + --no-restart → نافذة تعطّل.
- الذاكرة اليومية تجمّدت عند 10 يونيو لأن مرآة memory/→vault (sync_obsidian_vault.sh) أُضيفت أوتوماتيكياً اليوم فقط.
- الجوال (S24) كان "notSharing/Unused" لأنه لم يقبل المجلد؛ ثم قبله.
- تصحيح: openclaw-vault (2.56GiB) = المعرفة النصية المنسّقة بعد .stignore (يستثني venv/media/.git) — وهو المطلوب على الجوال، ليس junk.
المرحلة أ (منفّذة): حارس keepalive: مجسّ HTTP /rest/noauth/health (يغلق M-052 alive-but-dead) + log append(>>) مع تدوير 3000 سطر + قتل بالـPID. bash -n سليم.
المرحلة ب (منفّذة + متحقّقة): نقل Syncthing لحاوية Docker مستقلّة (
/docker/syncthing/docker-compose.yml) — نفس الباينري v2.1.1 (static) + نفس config → نفس device ID، restart:unless-stopped، mount المضيف الصحيح
/docker/openclaw-4x4t/data/.openclaw، ports 22000tcp+udp/21027udp منشورة (اتصال مباشر). sync-proxy backend حُوّل لـ syncthing:8384. حارس العملية العارية عُطّل ببوابة flag
/data/.openclaw/syncthing-config/.migrated-to-container (قابل للتراجع). rollback:
/docker/syncthing/rollback.sh. نسخة هوية احتياطية:
/docker/syncthing/config-identity-backup-.tar.gz.
النتيجة: container running/healthy 200، الجهازان متصلان (WaelGPD + SM-S928B)، sync.drwael... = OK، صفر بارِيّة مكرّرة، RAG/workspace غير متأثرين.
درس تشغيلي: docker exec داخل حاوية openclaw كان يُقطع بـ SIGTERM عند kill syncthing → الحل: عمليات host-side بمطابقة cgroup (docker inspect .Id) بدل docker exec.
M-077 addendum — .stignore gap-close (2026-07-06 ~17:45)
د. وائل: الجوال = obsidian-vault فقط (نُفّذ عبر API، أُزيل من openclaw-vault)؛ اللابتوب = كامل.
شيّك الـ2.56غ: junk تسرّب رغم .stignore بسبب ثغرات أنماط:
.venv لا يطابق .venvs (بالجمع) → بيئة leandojo 311م.
/db يطابق مجلدات لا ملفات → catalog.db 642م + .sqlite.
- لا استثناء dist/build/exe → projects/xo-game 1.7غ (مخرجات بناء) + arabic-tashkeel .pt 157م.
الحل (API POST /rest/db/ignores?folder=openclaw-vault، دمج مع 45 نمطاً موجوداً → 62): أضيف
.venvs .exe
.dll .so
.jar .dex
.apk .dat
.pak .pt
.pth .onnx
.db .sqlite
/dist /build
النتيجة: openclaw-vault localBytes نزل من 2749م → 670م (معرفة نقية)، 1422 md سليمة، الملفات المفتاحية حاضرة. globalBytes يبقى 2749م حتى ينظّف اللابتوب نسخه القديمة (Syncthing لا يحذف المستثنى على الأجهزة). درس: أنماط .stignore حرفية — .venv≠.venvs، */db=dirs لا files. سكربتات: projects/syncthing-migration/{unshare_phone,apply_ignores}.py.