2026-07-20 — يومية العمل
🏗️ مشروع: النسخة المحلية للترسانة على اللابتوب (Local Image + Launcher + التحديث التزايدي)
السياق: أمس (07-18) واليوم (07-19→20) نزّل د. وائل نسخة R2 على اللابتوب (GPD Win Max 2)، عمل restore على Docker وشغّلها. الهدف: launcher ذكي (دبل-كليك) + تحديث تزايدي من R2 (الفروقات فقط) دون مسح الإعدادات المحلية، ثم ربط بوت تيليجرام ثانٍ للنسخة المحلية.
🖥️ الطوبولوجيا الفعلية على اللابتوب (مؤكّدة من أوامر د. وائل — خط أحمر لا تخمين):
- WSL distro =
kali-linux(ليس Ubuntu) - جذر الاستعادة =
~/restore2/docker(=/home/wayrk/restore2/docker، مسارات Linux داخل WSL، مطابق للسيرفر 1:1) - هدف restic restore =
~/restore2(ينتج~/restore2/docker/...) - ملف الكومبوز المحلي =
docker-compose.local.yml(fallback:docker-compose.yml) - القلب =
openclaw-4x4t· n8n =n8n-proxy· الأكاديمية =academy-proxy+edulab+seclab - الأوامر تمر عبر PowerShell → WSL: يجب اقتباس مفرد
'...'وإلا PowerShell يُفسد$()و2>/dev/null(فشل «D:\dev\null»). درس مؤكّد. - PowerShell/conhost القديم لا يدعم عربي RTL أبداً (حروف مقلوبة). الحل: Windows Terminal من Store يدعم RTL. لذا واجهة اللانشر حُوّلت لإنجليزي ASCII لتعمل في أي طرفية.
🔑 اكتشاف مهم — مسار توكن تيليجرام في الإعداد المحلي:
- ليس
.channels.telegram.accounts.default.botToken(السيرفر) — بل.channels.telegram.botToken+.channels.telegram.allowFromفي نسخة اللابتوب. - لذلك PROTECT_KEYS في اللانشر يجب أن تشمل كلا المسارين (v4 يلتقط أيّهما وُجد).
✅ محرّك restic على السيرفر (مُنجَز ومُختبَر):
- restic 0.16.4 مثبّت على الـ host (Ubuntu 24.04، حيث تعيش
/docker+/var/lib/docker/volumes). - مستودع مشفّر جديد على R2:
s3:<R2_ENDPOINT>/kiloclaw/restic-server(مسار موازٍ، لا يمسّ التار-بول الكامل المشفّر الحالي). - بيانات الاعتماد على host:
/root/.restic_r2.env+ password-file/root/.restic_repo_password. ملف الاستثناءات/root/.restic_excludes. - السكربت:
scripts/restic_server_backup.sh(يُنسخ للـ host). keep-last 8 + prune. - البرهان الحيّ: أول snapshot كامل = 67.8 GiB (dedup+ضغط من ~100GB). التحديث التزايدي الثاني رفع 496MB فقط (فحص 551,998 ملف) — جوهر الفكرة مُثبَت.
restic check= صفر أخطاء.restic diffيعرض التغييرات. - الجدولة على الhost cron: restic أحد+خميس 06:00 (بعد التار-بول الكامل 04:00). النتيجة: R2 يحمل دائماً نسختين معاً (كاملة للاستعادة على أي جهاز + تزايدية للحقن في المحلي). هذا طلب د. وائل الصريح.
📦 حزمة اللانشر (projects/laptop-arsenal/local-image/):
arsenal.sh— اللانشر (bash داخل WSL، واجهة إنجليزي ASCII). أزرار: [1] Arsenal only [2] +n8n [3] Whole [4/5] Academic on/off [6] Update from R2 (diffs only) [7] Health [8] Stop all [9] Status [0] Exit.ARSENAL.bat— مشغّل دبل-كليك من ويندوز يستدعيwsl -d kali-linux -- bash -lc "~/arsenal-launcher/arsenal.sh ...".install_wsl.sh— bootstrap: يثبّت restic+jq، ينسخ لـ~/arsenal-launcher/, يضع restic_r2.env، يتحقق من R2.restic_r2.env(معبّأ بالمفاتيح الفعلية) +.template.README_LOCAL_IMAGE.md— الدليل.- معمارية الحماية: Base (تتحدّث من R2) + Protected Overlay (توكن/allowFrom/ملفات محلية تُحفظ في
local-overlay/وتُعاد بعد كل تحديث عبر jq deep-merge). النسخة المحلية = fork لا مرآة. - تدفّق زر [6]: read snapshots → diff preview → capture_overlay → stop containers →
restic restore latest --include /docker --target ~/restore2→ apply_overlay → record snapshot.
🐛 دورة الإصلاحات (v1→v4):
- v1 (PowerShell): خطأ — الطوبولوجيا WSL لا ويندوز. أُلغيت.
- v2 (bash إنجليزي): نجح فعلياً على لابتوب د. وائل — التحديث التزايدي اشتغل (snapshot b6085ddb). لكن التقط
.channels.telegram.allowFromفقط وفوّت botToken (مسار مختلف). - v3: أضاف مسار
.channels.telegram.botToken. لكنrestic restoreتعثّر بـ 20 خطأ symlink حميدة (RemoveNode: directory not emptyعلى skills/media-use…) → السكربت أوقف rc=1 خطأً. Restored 76483/76502، skipped 550944 (125GB base موجود). - v4 (النهائي المُرسَل): يتجاهل أخطاء symlink/RemoveNode الحميدة (restore rc تعامل كنجاح جزئي مقبول) + يعيد تشغيل ما كان شغّالاً تلقائياً بعد الاستعادة. مُحزَّم ومُرسَل (رسالة ~29785) + أمر تطبيق بزر نسخ.
⏳ المتبقّي (لم يكتمل بعد):
1. تأكيد نجاح v4 على اللابتوب (د. وائل سيجرّب: فك ضغط v4 → تطبيق → [3] Whole → [6] Update). بانتظار مخرجاته. 2. ربط البوت الثاني للنسخة المحلية — يحتاج د. وائل يعطي توكن BotFather جديد → يُربط في الطبقة المحميّة (يعمل مع الأساسي بلا تعارض). 3. تفعيل الاقتراحات الذكية — أوصيتُ بالبدء بـ توجيه العقل للـ NPU المحلي (Ryzen AI 9 HX 370 + XDNA2 NPU + Radeon 890M + 64GB): LLM محلي + Whisper + Kokoro + صور offline. + auto-rollback (restic 8 snapshots) + تحديث أسبوعي (Task Scheduler) + RAM-disk 16GB cache + bootstrap لأي جهاز جديد.📌 دروس/قواعد:
- M-076 تكرر: حلقات المتابعة (polling) سرّبت إشعار
Exec failed: run -op ...أحمر لد. وائل (صورة). حميد تماماً — العمل نجح بعده. القاعدة: لفّ كل متابعة بصمت تام (|| true,timeout N), لا process kill يدوي (استخدمت process action=kill بدل pkill بنجاح). - تسليم الملفات لتيليجرام: نُقلت الحزمة من
/tmp(مرفوض) إلى مجلد الوسائط المعتمد ثم أُرسلت. أوامر النسخ أُرسلت عبرscripts/tg_code.sh(أزرار Copy عاملة). - اللابتوب ليس node مربوطاً — أسلّم السكربتات ويشغّلها د. وائل بنفسه.
🐛 دورة الإصلاحات (v5→v6):
- v5 فشل بخطأ برمجي مني (regression): أضفتُ
--exclude '/docker/.../skills'لأمرrestic restoreالذي فيه أصلاً--include /docker. restic يرفض دمجهما →Fatal: exclude and include patterns are mutually exclusive→ الأمر يفشل قبل أن يبدأ (rc=1). - درس دائم:
restic restore—--includeو--excludeمتنافيان (mutually exclusive). لا تدمجهما أبداً. استخدم واحداً فقط. - v6 (الإصلاح النظيف): حذفتُ سطر
--excludeتماماً، أُبقي--include /dockerفقط. النجاح يُحكَم حصراً بالمعيار المتين:openclaw.jsonموجود + صالح JSON (jq -e) — لا بـ rc ولا بعدّ الأخطاء. أخطاء الـ symlink الـ20 الحميدة تظهر (rc=1) لكن لا تُفشِل التحديث. الاستعادة نفسها نجحت فعلياً في كل المحاولات (76483/76502) — المشكلة كانت فقط في حكم النجاح. - الحزمة:
media/outbound/arsenal-local-image-v6-20260720.zip(6 ملفات، arsenal.sh مُصحَّح، bash -n OK). أُرسلت + أمر التطبيق عبر tg_code.sh.
✅ v6 نجح (2026-07-20 04:29) — المشروع مكتمل:
- التحديث التزايدي اكتمل: «restore OK with 20 non-fatal warnings; config valid JSON - continuing» → «re-applied 2 local key(s) (token/links preserved)» → «recorded snapshot: b6085ddb».
- التوكن + allowFrom محفوظان عبر التحديث (حماية الـ overlay تعمل). snapshot تُسجَّل الآن فيعمل «already up to date» مستقبلاً.
- سلوك «no stacks were running before - pick [1]/[2]/[3]» صحيح (كان أوقف الكل قبلها).
- الخلاصة النهائية: اللانشر المحلي للترسانة (start/stop groups + academic + incremental R2 update + token protection) مكتمل ومختبَر E2E على لابتوب د. وائل (WSL kali-linux، ~/restore2/docker). النسخة النهائية = v6.
🐛 v7 — إصلاح فشل تشغيل الحاويات (2026-07-20 05:09):
- العرض: [3] Whole شغّل بعض الستاكات وفشل: academy-proxy, apps-proxy, ask-proxy, bot-proxy, cost-proxy, code, couchdb.
- السبب الجذري (مؤكّد من خطأ docker الحرفي — لا تخمين):
network openclaw-4x4t_default declared as external, but could not be found. الشبكة المشتركة يُنشئها ستاك openclaw-4x4t (اسم المشروع الافتراضي)، والباقي يتعلّق بها external. الترتيب الأبجدي يشغّل bot-proxy(b)/code(c)/couchdb(c)/الـproxies قبل openclaw-4x4t(o) → الشبكة غير موجودة → فشل. على السيرفر الشبكة موجودة أصلاً؛ على اللابتوب بعد الاستعادة لم يُنشئها أحد. - الحل v7 (طبقتان): (1) CORE أُعيد ترتيبه: openclaw-4x4t أولاً + start_whole يشغّله قبل الكل (ينشئ الشبكة بتسمياتها). (2) self-heal في up_stack: عند فشل، يقرأ اسم الشبكة الناقصة من خطأ docker،
docker network createلها، ويعيد المحاولة مرة — مستقل عن الترتيب، يغطّي أي شبكة خارجية أخرى. - درس دائم: ستاكات docker-compose المنفصلة التي تشترك شبكة خارجية (
X_defaultexternal) تحتاج الستاك المالك يبدأ أولاً، أو pre-create للشبكة. self-heal من قراءة خطأ docker = الأمتن. - الحزمة: arsenal-local-image-v7-20260720.zip (bash -n OK). أُرسلت + أمر التطبيق (stop all ثم whole) عبر tg_code.sh.
- ⚠️ M-076 تكرر: قتلتُ عملية find يدوياً → تسرّب إشعار «Process: tide-sable failed» لتيليجرام. القاعدة: لا قتل exec يدوي — استخدم timeout داخل الأمر.
🐛 v8 — إصلاح تعارض شبكة المالك + inline errors (2026-07-20 05:27):
- تقدّم v7: openclaw-4x4t بدأ أولاً وأنشأ شبكته ✅، self-heal اشتغل فعلياً (أنشأ redis-arsenal_default لـ monitoring). لكن redis-arsenal (مالك redis-arsenal_default) فشل: self-heal أنشأ الشبكة عادية (بلا تسميات compose) عند حاجة monitoring المبكرة → لمّا جاء دور المالك وجدها بتسمية خاطئة → تعارض. + فشل local-ai/navidrome/obsidian-proxy/panel/pascal/push (أسباب غير معروفة بعد).
- الحل v8 (3 تحسينات): (1) CORE = ملّاك الشبكات أولاً معاً:
openclaw-4x4t redis-arsenal traefik bot-proxy+ start_whole يشغّل كل CORE قبل المستهلكين. (2) self-heal case B: عند «network X was found but has incorrect label» يحذف الشبكة العادية المتعارضة (آمن بعد Stop all، لا endpoints) ويعيد المحاولة فيُنشئها المالك بتسمياتها. (3) طباعة سبب أي فشل inline تحت السطر (> ...) لحسم الباقي في تشغيلة واحدة. - درس دائم: self-heal الذي ينشئ شبكة يملكها ستاك آخر = تعارض تسميات. الحل: تشغيل الملّاك أولاً + حذف الشبكة العادية المتعارضة عند فشل المالك. لا تُنشئ شبكة قد يملكها compose.
- الحزمة: arsenal-local-image-v8-20260720.zip (bash -n OK). أُرسلت (msg 29840). الخطوات: [8] Stop all → [3] Whole → [7]. بانتظار مخرجات [3] (ستُظهر أسباب أي فشل متبقٍ inline).
🐛 v9 — نفاد شبكات docker + inline errors كشفت كل الأسباب (2026-07-20 05:42):
- تقدّم v8: 35 حاوية تعمل. redis-arsenal اتصلحت («removed conflicting network → up»). الطباعة inline كشفت كل الأسباب.
- openclaw-4x4t «not running» = إنذار كاذب: اسم حاويته الفعلي
openclaw-local(Up 5min، يعمل). health كان يبحث عن «openclaw-4x4t» → صحّحته لـopenclaw-local. - السبب الكبير (11 ستاك):
all predefined address pools have been fully subnetted. docker الافتراضي يقسّم 172.17-172.31 لـ/16 = ~31 شبكة فقط (كان عندنا 33). الحل: daemon.jsondefault-address-pools(base 10.210.0.0/16 + 10.211.0.0/16, size 24 = 512 شبكة). daemon.json غير موجود → أُنشئ نظيفاً. - local-ai: تعارض اسم حاوية
open-webuiعالقة → self-heal case C (grep «container name "/X"» → docker rm -f → retry) — مُضاف. - syncthing: يشير لملف ثنائي
/data/.openclaw/tools/bin/syncthingغير موجود على اللابتوب (خاص بالسيرفر). threadfin: وسم صورةfyb3roptik/threadfin:0.5.0محذوف من Docker Hub. كلاهما → SKIP_LAPTOP list (تخطّي نظيف مع note). - التسليم: v9 zip (bash -n OK، msg 29859) + أمر1 (تطبيق v9 + docker rm -f الكل + network prune + كتابة daemon.json + service docker restart → DOCKER_OK) + أمر2 (فتح اللانشر → [3] → [7]). عبر tg_code.sh.
- درس دائم: docker يُنفد نطاقات العناوين الافتراضية عند ~31 شبكة (172.17-172.31/16). أي بيئة بكثير من الستاكات المنفصلة تحتاج
default-address-poolsموسّعة في daemon.json من البداية.
🐛 v9 تشغيل + دروس بيئة Docker Desktop/WSL (2026-07-20 06:20):
- daemon.json داخل kali يُتجاهَل: docker على اللابتوب = Docker Desktop (لا dockerd داخل kali، السياق
desktop-linux، socket unix:///var/run/docker.sock جسر لويندوز). التوسيع الصحيح لـdefault-address-pools= واجهة Docker Desktop → Settings → Docker Engine → Apply & Restart (وليس /etc/docker/daemon.json في kali). تحقّق:docker network create _pooltest→ POOL=10.210.1.0/24 ✅. - Docker Desktop «Apply & Restart» ينفّذ
wsl --shutdown: يُعلّق توزيعة kali (تظهر Running لكن لا تنفّذ أوامر → مخرجات فارغة). الحل:wsl --terminate kali-linuxثم أمر جديد يُعيد إحياءها (تحذير systemd user session حميد). سقوط المحرك وسط [3] = ضغط 30 ستاك دفعة + نافذة إعادة التشغيل، ليس خطأ سكربت. - تعارض تيليجرام (خطر مزدوج): بوت اللابتوب (حاوية اسمها
openclaw-local) = نسخة DR بنفس التوكن → getUpdates conflict + ينفّذ أوامر د. وائل بشكل مستقل (نسختان تتصارعان). الحل الدائم: تعطيل تيليجرام في إعداد اللابتوبchannels.telegram.enabled=false(backup: openclaw.json.telegram-off.bak، التوكن سليم) → يبقى «دماغ DR» صامتاً و[3] آمن. عند تعطّل السيرفر فعلاً: يُفعّل بسطر. - 🔴 درس PowerShell حاسم (paste artifact): عند لصق
wsl -d kali-linux -- bash -c '...'في PowerShell، المتغيّرات المُسنَدة حديثاً داخل bash (f=...; $f) ترجع فارغة (بينما env vars مثل$HOMEتعمل) →cp: cannot stat ''+NOT_FOUNDكاذب. القاعدة: كل أمر يُلصَق في PowerShell/WSL يجب أن يستخدم مسارات حرفية كاملة، صفر متغيّرات$وصفر$(...)، وصفر backup names بـ $(date) — استخدم أسماء ثابتة. الأمر الحرفي نجح فوراً. - مسار config اللابتوب المؤكّد:
/home/wayrk/restore2/docker/openclaw-4x4t/data/.openclaw/openclaw.json(29224 bytes). container يمنت./data:/data.
✅✅ المشروع اكتمل — GREEN كامل (2026-07-20 06:21):
- [3] Whole → 48 حاوية تعمل، Result: GREEN. كل الـ11 ستاك السابقة الفاشلة (navidrome/panel/pascal/push/twin/wiki-proxy/seclab/status/studio/obsidian-proxy/sync-proxy) = OK بعد توسيع الشبكات. local-ai=OK (self-heal). syncthing+threadfin تُخطّيا بنظافة. openclaw-local=Up (تيليجرام معطّل، صفر تعارض). redis-arsenal healthy.
- النسخة النهائية = v9. نسخة DR على لابتوب د. وائل مكتملة ومختبَرة E2E: تحديث R2 تزايدي (restic) + تشغيل مجموعات [1/2/3] + أكاديمي [4/5] + حماية التوكن (overlay) + self-heal شبكات/حاويات + تخطّي غير المتوافق + دماغ openclaw صامت (يُفعّل بقلب enabled=true عند تعطّل السيرفر).
- رحلة الإصلاح: v6 (restic include/exclude) → v7 (ترتيب ملّاك الشبكات + net self-heal) → v8 (تعارض شبكة المالك + inline errors) → v9 (default-address-pools في Docker Desktop UI + container self-heal + SKIP_LAPTOP + telegram off).
✅ ترقية نواة OpenClaw على اللابتوب (2026-07-20 06:36):
- سؤال د. وائل: لماذا اللابتوب على 2026.6.11 بينما السيرفر (والأصل) على 2026.7.1-2 رغم [6] Update from R2؟
- الجواب المؤكّد (مصادر حيّة): [6] Update from R2 = مزامنة بيانات/إعدادات/ذاكرة/skills فقط، لا يرقّي النواة. السبب: كلا سكربتَي النسخ (
full_server_backup.sh+full_server_secure_backup.sh) يستثنيان/node_modulesصراحةً (النواة 7.4GB في /data/.npm-global، قابلة لإعادة التوليد). دليل حاسم: استعادة [6] كتبت 53.9KiB فقط (لا مئات MB). السيرفر رُقّي 2026-07-19 17:25. - اللابتوب: PREFIX=/data/.npm-global (على الـ volume، دائم)، WHICH=/data/.npm-global/bin/openclaw، الإصدار كان 2026.6.11.
- الترقية:
docker exec openclaw-local npm install -g openclaw@2026.7.1-2 && docker restart openclaw-local→ NEWVER=2026.7.1-2 (0790d9f) — مطابق للسيرفر. (28s، تحذيرات allow-scripts حميدة.) - درس/قاعدة دائمة: [6] = data sync. ترقية النواة = خطوة منفصلة صريحة (
npm install -g openclaw@<version>داخل الحاوية، إصدار محدّد لاnpm update -g). تُطبَّق عند صدور إصدار جديد على السيرفر لمطابقة اللابتوب. - المشروع مكتمل 100%: 48 حاوية GREEN + إصدار مطابق + DR جاهز.
📋 خطة الترسانة المحلية — التوصيات النهائية (2026-07-20 07:05):
- الوثيقة:
projects/laptop-arsenal/MASTER_PLAN_LOCAL.md(أُرسلت msg 29994). - الرؤية: المحلي = عقدة متوازية متخصّصة (DR + خصوصية + Academy غير مقيّد بنموذج محلي + استغلال عتاد اللابتوب GPD Win Max 2: NPU/Radeon 890M/64GB)، ليس مجرد DR mirror. الحيّ يبقى المرجع الأساسي.
- قرارات: (1) مزامنة أحادية الاتجاه حيّ←محلي كل 3 أيام عبر [6] R2 مجدولة (Task Scheduler) — أأمن من syncthing المباشر على بيانات openclaw الحيّة. (2) بوت تيليجرام ثانٍ منفصل (BotFather) — أفضل من re-enable الطارئ. (3) Portal محلي بروابط localhost. (4) استغلال العتاد + نموذج محلي Qwen~32B uncensored لـ Academy (بصدق: NPU XDNA دعمه ناشئ؛ المكسب = خصوصية+غير مقيّد+offline). (5) أيقونة رابعة + إشعار إقلاع + فحص إصدار تلقائي + جدولة.
- 🔒 متطلب صارم د. وائل: المزامنة تنقل كل شيء إلا هوية تيليجرام (توكن+allowFrom+enabled) — البوت المحلي منفصل 100%، صفر تعارض. مضمون عبر: overlay يحفظ هوية تيليجرام (سأوسّعه ليحمي enabled أيضاً) + الأيقونات/اللانشر خارج شجرة /docker (لا تُمَسّ بالمزامنة) + Portal محمي + [6] فيه تحقّق JSON + rollback + health (لا انهيار).
- فحص إصدار للتطابق مع الحيّ: الحيّ يكتب إصداره في
memory/live_openclaw_version.txt(يُنسَخ R2) → المحلي يثبّت نفس إصدار الحيّ بالضبط بعد [6] (لا npm-latest). - ⏳ منتظر من د. وائل (3 مدخلات): (1) مخرجات docker ps المنافذ (لبناء Portal) (2) توكن البوت الثاني (3) ollama list على اللابتوب. البدء المقترح: المرحلة 1 (إصلاحات threadfin/syncthing/daemon + Portal + أيقونات) فور وصول المنافذ.
- أوامر أُرسلت بانتظار تشغيل د. وائل: fix_threadfin + حصر المنافذ (docker ps) + (سابقاً) الأيقونات (نجحت).
🧠 مراجعة الصباح — تنفيذ (11:38–11:55)
- uncensored.com: السبب الجذري = موجود في liberation_router Tier0 لكن غائب عن cron النشرة + capabilities_watch. أُضيف للاثنين. فحص حي: 71 models؛ Gemini 3.1 Pro/DeepSeek V4/R1 ✅؛ academic_readiness RC=0 وكل المزودين HTTP 200.
- Ollama: رُقّي 0.24.0 → 0.32.1؛ backup كامل
/data/.local/ollama-install.backup-0.24.0-20260720. API+5 models+توليد OLLAMA_OK نجح. خلل trap أثناء swap عولج فوراً قبل التسليم. - Unified Brain: تقرير
projects/unified-brain/ARCHITECTURE_REVIEW.md. القرار = Thin Facade جديد فوق الخدمات القائمة، لا monolith؛ shadow→canary→promote، rollback بإزالة route واحد. - MCP Generator: حُدّد كـ Postman MCP Generator (لا OpenAI generator). POC معزول APS+Paperclip نجح 6 tools. رُفض Postman SaaS للإنتاج واعتمد النمط المحلي؛ سُجل
mcp-aps-paperclipفي mcporter وlist/call نجح. لا تعديلات على تكاملات APS/Paperclip الأصلية.
2026-07-20 — يومية العمل
🏗️ مشروع: النسخة المحلية للترسانة على اللابتوب (Local Image + Launcher + التحديث التزايدي)
السياق: أمس (07-18) واليوم (07-19→20) نزّل د. وائل نسخة R2 على اللابتوب (GPD Win Max 2)، عمل restore على Docker وشغّلها. الهدف: launcher ذكي (دبل-كليك) + تحديث تزايدي من R2 (الفروقات فقط) دون مسح الإعدادات المحلية، ثم ربط بوت تيليجرام ثانٍ للنسخة المحلية.
🖥️ الطوبولوجيا الفعلية على اللابتوب (مؤكّدة من أوامر د. وائل — خط أحمر لا تخمين):
- WSL distro =
kali-linux(ليس Ubuntu) - جذر الاستعادة =
~/restore2/docker(=/home/wayrk/restore2/docker، مسارات Linux داخل WSL، مطابق للسيرفر 1:1) - هدف restic restore =
~/restore2(ينتج~/restore2/docker/...) - ملف الكومبوز المحلي =
docker-compose.local.yml(fallback:docker-compose.yml) - القلب =
openclaw-4x4t· n8n =n8n-proxy· الأكاديمية =academy-proxy+edulab+seclab - الأوامر تمر عبر PowerShell → WSL: يجب اقتباس مفرد
'...'وإلا PowerShell يُفسد$()و2>/dev/null(فشل «D:\dev\null»). درس مؤكّد. - PowerShell/conhost القديم لا يدعم عربي RTL أبداً (حروف مقلوبة). الحل: Windows Terminal من Store يدعم RTL. لذا واجهة اللانشر حُوّلت لإنجليزي ASCII لتعمل في أي طرفية.
🔑 اكتشاف مهم — مسار توكن تيليجرام في الإعداد المحلي:
- ليس
.channels.telegram.accounts.default.botToken(السيرفر) — بل.channels.telegram.botToken+.channels.telegram.allowFromفي نسخة اللابتوب. - لذلك PROTECT_KEYS في اللانشر يجب أن تشمل كلا المسارين (v4 يلتقط أيّهما وُجد).
✅ محرّك restic على السيرفر (مُنجَز ومُختبَر):
- restic 0.16.4 مثبّت على الـ host (Ubuntu 24.04، حيث تعيش
/docker+/var/lib/docker/volumes). - مستودع مشفّر جديد على R2:
s3:<R2_ENDPOINT>/kiloclaw/restic-server(مسار موازٍ، لا يمسّ التار-بول الكامل المشفّر الحالي). - بيانات الاعتماد على host:
/root/.restic_r2.env+ password-file/root/.restic_repo_password. ملف الاستثناءات/root/.restic_excludes. - السكربت:
scripts/restic_server_backup.sh(يُنسخ للـ host). keep-last 8 + prune. - البرهان الحيّ: أول snapshot كامل = 67.8 GiB (dedup+ضغط من ~100GB). التحديث التزايدي الثاني رفع 496MB فقط (فحص 551,998 ملف) — جوهر الفكرة مُثبَت.
restic check= صفر أخطاء.restic diffيعرض التغييرات. - الجدولة على الhost cron: restic أحد+خميس 06:00 (بعد التار-بول الكامل 04:00). النتيجة: R2 يحمل دائماً نسختين معاً (كاملة للاستعادة على أي جهاز + تزايدية للحقن في المحلي). هذا طلب د. وائل الصريح.
📦 حزمة اللانشر (projects/laptop-arsenal/local-image/):
arsenal.sh— اللانشر (bash داخل WSL، واجهة إنجليزي ASCII). أزرار: [1] Arsenal only [2] +n8n [3] Whole [4/5] Academic on/off [6] Update from R2 (diffs only) [7] Health [8] Stop all [9] Status [0] Exit.ARSENAL.bat— مشغّل دبل-كليك من ويندوز يستدعيwsl -d kali-linux -- bash -lc "~/arsenal-launcher/arsenal.sh ...".install_wsl.sh— bootstrap: يثبّت restic+jq، ينسخ لـ~/arsenal-launcher/, يضع restic_r2.env، يتحقق من R2.restic_r2.env(معبّأ بالمفاتيح الفعلية) +.template.README_LOCAL_IMAGE.md— الدليل.- معمارية الحماية: Base (تتحدّث من R2) + Protected Overlay (توكن/allowFrom/ملفات محلية تُحفظ في
local-overlay/وتُعاد بعد كل تحديث عبر jq deep-merge). النسخة المحلية = fork لا مرآة. - تدفّق زر [6]: read snapshots → diff preview → capture_overlay → stop containers →
restic restore latest --include /docker --target ~/restore2→ apply_overlay → record snapshot.
🐛 دورة الإصلاحات (v1→v4):
- v1 (PowerShell): خطأ — الطوبولوجيا WSL لا ويندوز. أُلغيت.
- v2 (bash إنجليزي): نجح فعلياً على لابتوب د. وائل — التحديث التزايدي اشتغل (snapshot b6085ddb). لكن التقط
.channels.telegram.allowFromفقط وفوّت botToken (مسار مختلف). - v3: أضاف مسار
.channels.telegram.botToken. لكنrestic restoreتعثّر بـ 20 خطأ symlink حميدة (RemoveNode: directory not emptyعلى skills/media-use…) → السكربت أوقف rc=1 خطأً. Restored 76483/76502، skipped 550944 (125GB base موجود). - v4 (النهائي المُرسَل): يتجاهل أخطاء symlink/RemoveNode الحميدة (restore rc تعامل كنجاح جزئي مقبول) + يعيد تشغيل ما كان شغّالاً تلقائياً بعد الاستعادة. مُحزَّم ومُرسَل (رسالة ~29785) + أمر تطبيق بزر نسخ.
⏳ المتبقّي (لم يكتمل بعد):
1. تأكيد نجاح v4 على اللابتوب (د. وائل سيجرّب: فك ضغط v4 → تطبيق → [3] Whole → [6] Update). بانتظار مخرجاته. 2. ربط البوت الثاني للنسخة المحلية — يحتاج د. وائل يعطي توكن BotFather جديد → يُربط في الطبقة المحميّة (يعمل مع الأساسي بلا تعارض). 3. تفعيل الاقتراحات الذكية — أوصيتُ بالبدء بـ توجيه العقل للـ NPU المحلي (Ryzen AI 9 HX 370 + XDNA2 NPU + Radeon 890M + 64GB): LLM محلي + Whisper + Kokoro + صور offline. + auto-rollback (restic 8 snapshots) + تحديث أسبوعي (Task Scheduler) + RAM-disk 16GB cache + bootstrap لأي جهاز جديد.📌 دروس/قواعد:
- M-076 تكرر: حلقات المتابعة (polling) سرّبت إشعار
Exec failed: run -op ...أحمر لد. وائل (صورة). حميد تماماً — العمل نجح بعده. القاعدة: لفّ كل متابعة بصمت تام (|| true,timeout N), لا process kill يدوي (استخدمت process action=kill بدل pkill بنجاح). - تسليم الملفات لتيليجرام: نُقلت الحزمة من
/tmp(مرفوض) إلى مجلد الوسائط المعتمد ثم أُرسلت. أوامر النسخ أُرسلت عبرscripts/tg_code.sh(أزرار Copy عاملة). - اللابتوب ليس node مربوطاً — أسلّم السكربتات ويشغّلها د. وائل بنفسه.
🐛 دورة الإصلاحات (v5→v6):
- v5 فشل بخطأ برمجي مني (regression): أضفتُ
--exclude '/docker/.../skills'لأمرrestic restoreالذي فيه أصلاً--include /docker. restic يرفض دمجهما →Fatal: exclude and include patterns are mutually exclusive→ الأمر يفشل قبل أن يبدأ (rc=1). - درس دائم:
restic restore—--includeو--excludeمتنافيان (mutually exclusive). لا تدمجهما أبداً. استخدم واحداً فقط. - v6 (الإصلاح النظيف): حذفتُ سطر
--excludeتماماً، أُبقي--include /dockerفقط. النجاح يُحكَم حصراً بالمعيار المتين:openclaw.jsonموجود + صالح JSON (jq -e) — لا بـ rc ولا بعدّ الأخطاء. أخطاء الـ symlink الـ20 الحميدة تظهر (rc=1) لكن لا تُفشِل التحديث. الاستعادة نفسها نجحت فعلياً في كل المحاولات (76483/76502) — المشكلة كانت فقط في حكم النجاح. - الحزمة:
media/outbound/arsenal-local-image-v6-20260720.zip(6 ملفات، arsenal.sh مُصحَّح، bash -n OK). أُرسلت + أمر التطبيق عبر tg_code.sh.
✅ v6 نجح (2026-07-20 04:29) — المشروع مكتمل:
- التحديث التزايدي اكتمل: «restore OK with 20 non-fatal warnings; config valid JSON - continuing» → «re-applied 2 local key(s) (token/links preserved)» → «recorded snapshot: b6085ddb».
- التوكن + allowFrom محفوظان عبر التحديث (حماية الـ overlay تعمل). snapshot تُسجَّل الآن فيعمل «already up to date» مستقبلاً.
- سلوك «no stacks were running before - pick [1]/[2]/[3]» صحيح (كان أوقف الكل قبلها).
- الخلاصة النهائية: اللانشر المحلي للترسانة (start/stop groups + academic + incremental R2 update + token protection) مكتمل ومختبَر E2E على لابتوب د. وائل (WSL kali-linux، ~/restore2/docker). النسخة النهائية = v6.
🐛 v7 — إصلاح فشل تشغيل الحاويات (2026-07-20 05:09):
- العرض: [3] Whole شغّل بعض الستاكات وفشل: academy-proxy, apps-proxy, ask-proxy, bot-proxy, cost-proxy, code, couchdb.
- السبب الجذري (مؤكّد من خطأ docker الحرفي — لا تخمين):
network openclaw-4x4t_default declared as external, but could not be found. الشبكة المشتركة يُنشئها ستاك openclaw-4x4t (اسم المشروع الافتراضي)، والباقي يتعلّق بها external. الترتيب الأبجدي يشغّل bot-proxy(b)/code(c)/couchdb(c)/الـproxies قبل openclaw-4x4t(o) → الشبكة غير موجودة → فشل. على السيرفر الشبكة موجودة أصلاً؛ على اللابتوب بعد الاستعادة لم يُنشئها أحد. - الحل v7 (طبقتان): (1) CORE أُعيد ترتيبه: openclaw-4x4t أولاً + start_whole يشغّله قبل الكل (ينشئ الشبكة بتسمياتها). (2) self-heal في up_stack: عند فشل، يقرأ اسم الشبكة الناقصة من خطأ docker،
docker network createلها، ويعيد المحاولة مرة — مستقل عن الترتيب، يغطّي أي شبكة خارجية أخرى. - درس دائم: ستاكات docker-compose المنفصلة التي تشترك شبكة خارجية (
X_defaultexternal) تحتاج الستاك المالك يبدأ أولاً، أو pre-create للشبكة. self-heal من قراءة خطأ docker = الأمتن. - الحزمة: arsenal-local-image-v7-20260720.zip (bash -n OK). أُرسلت + أمر التطبيق (stop all ثم whole) عبر tg_code.sh.
- ⚠️ M-076 تكرر: قتلتُ عملية find يدوياً → تسرّب إشعار «Process: tide-sable failed» لتيليجرام. القاعدة: لا قتل exec يدوي — استخدم timeout داخل الأمر.
🐛 v8 — إصلاح تعارض شبكة المالك + inline errors (2026-07-20 05:27):
- تقدّم v7: openclaw-4x4t بدأ أولاً وأنشأ شبكته ✅، self-heal اشتغل فعلياً (أنشأ redis-arsenal_default لـ monitoring). لكن redis-arsenal (مالك redis-arsenal_default) فشل: self-heal أنشأ الشبكة عادية (بلا تسميات compose) عند حاجة monitoring المبكرة → لمّا جاء دور المالك وجدها بتسمية خاطئة → تعارض. + فشل local-ai/navidrome/obsidian-proxy/panel/pascal/push (أسباب غير معروفة بعد).
- الحل v8 (3 تحسينات): (1) CORE = ملّاك الشبكات أولاً معاً:
openclaw-4x4t redis-arsenal traefik bot-proxy+ start_whole يشغّل كل CORE قبل المستهلكين. (2) self-heal case B: عند «network X was found but has incorrect label» يحذف الشبكة العادية المتعارضة (آمن بعد Stop all، لا endpoints) ويعيد المحاولة فيُنشئها المالك بتسمياتها. (3) طباعة سبب أي فشل inline تحت السطر (> ...) لحسم الباقي في تشغيلة واحدة. - درس دائم: self-heal الذي ينشئ شبكة يملكها ستاك آخر = تعارض تسميات. الحل: تشغيل الملّاك أولاً + حذف الشبكة العادية المتعارضة عند فشل المالك. لا تُنشئ شبكة قد يملكها compose.
- الحزمة: arsenal-local-image-v8-20260720.zip (bash -n OK). أُرسلت (msg 29840). الخطوات: [8] Stop all → [3] Whole → [7]. بانتظار مخرجات [3] (ستُظهر أسباب أي فشل متبقٍ inline).
🐛 v9 — نفاد شبكات docker + inline errors كشفت كل الأسباب (2026-07-20 05:42):
- تقدّم v8: 35 حاوية تعمل. redis-arsenal اتصلحت («removed conflicting network → up»). الطباعة inline كشفت كل الأسباب.
- openclaw-4x4t «not running» = إنذار كاذب: اسم حاويته الفعلي
openclaw-local(Up 5min، يعمل). health كان يبحث عن «openclaw-4x4t» → صحّحته لـopenclaw-local. - السبب الكبير (11 ستاك):
all predefined address pools have been fully subnetted. docker الافتراضي يقسّم 172.17-172.31 لـ/16 = ~31 شبكة فقط (كان عندنا 33). الحل: daemon.jsondefault-address-pools(base 10.210.0.0/16 + 10.211.0.0/16, size 24 = 512 شبكة). daemon.json غير موجود → أُنشئ نظيفاً. - local-ai: تعارض اسم حاوية
open-webuiعالقة → self-heal case C (grep «container name "/X"» → docker rm -f → retry) — مُضاف. - syncthing: يشير لملف ثنائي
/data/.openclaw/tools/bin/syncthingغير موجود على اللابتوب (خاص بالسيرفر). threadfin: وسم صورةfyb3roptik/threadfin:0.5.0محذوف من Docker Hub. كلاهما → SKIP_LAPTOP list (تخطّي نظيف مع note). - التسليم: v9 zip (bash -n OK، msg 29859) + أمر1 (تطبيق v9 + docker rm -f الكل + network prune + كتابة daemon.json + service docker restart → DOCKER_OK) + أمر2 (فتح اللانشر → [3] → [7]). عبر tg_code.sh.
- درس دائم: docker يُنفد نطاقات العناوين الافتراضية عند ~31 شبكة (172.17-172.31/16). أي بيئة بكثير من الستاكات المنفصلة تحتاج
default-address-poolsموسّعة في daemon.json من البداية.
🐛 v9 تشغيل + دروس بيئة Docker Desktop/WSL (2026-07-20 06:20):
- daemon.json داخل kali يُتجاهَل: docker على اللابتوب = Docker Desktop (لا dockerd داخل kali، السياق
desktop-linux، socket unix:///var/run/docker.sock جسر لويندوز). التوسيع الصحيح لـdefault-address-pools= واجهة Docker Desktop → Settings → Docker Engine → Apply & Restart (وليس /etc/docker/daemon.json في kali). تحقّق:docker network create _pooltest→ POOL=10.210.1.0/24 ✅. - Docker Desktop «Apply & Restart» ينفّذ
wsl --shutdown: يُعلّق توزيعة kali (تظهر Running لكن لا تنفّذ أوامر → مخرجات فارغة). الحل:wsl --terminate kali-linuxثم أمر جديد يُعيد إحياءها (تحذير systemd user session حميد). سقوط المحرك وسط [3] = ضغط 30 ستاك دفعة + نافذة إعادة التشغيل، ليس خطأ سكربت. - تعارض تيليجرام (خطر مزدوج): بوت اللابتوب (حاوية اسمها
openclaw-local) = نسخة DR بنفس التوكن → getUpdates conflict + ينفّذ أوامر د. وائل بشكل مستقل (نسختان تتصارعان). الحل الدائم: تعطيل تيليجرام في إعداد اللابتوبchannels.telegram.enabled=false(backup: openclaw.json.telegram-off.bak، التوكن سليم) → يبقى «دماغ DR» صامتاً و[3] آمن. عند تعطّل السيرفر فعلاً: يُفعّل بسطر. - 🔴 درس PowerShell حاسم (paste artifact): عند لصق
wsl -d kali-linux -- bash -c '...'في PowerShell، المتغيّرات المُسنَدة حديثاً داخل bash (f=...; $f) ترجع فارغة (بينما env vars مثل$HOMEتعمل) →cp: cannot stat ''+NOT_FOUNDكاذب. القاعدة: كل أمر يُلصَق في PowerShell/WSL يجب أن يستخدم مسارات حرفية كاملة، صفر متغيّرات$وصفر$(...)، وصفر backup names بـ $(date) — استخدم أسماء ثابتة. الأمر الحرفي نجح فوراً. - مسار config اللابتوب المؤكّد:
/home/wayrk/restore2/docker/openclaw-4x4t/data/.openclaw/openclaw.json(29224 bytes). container يمنت./data:/data.
✅✅ المشروع اكتمل — GREEN كامل (2026-07-20 06:21):
- [3] Whole → 48 حاوية تعمل، Result: GREEN. كل الـ11 ستاك السابقة الفاشلة (navidrome/panel/pascal/push/twin/wiki-proxy/seclab/status/studio/obsidian-proxy/sync-proxy) = OK بعد توسيع الشبكات. local-ai=OK (self-heal). syncthing+threadfin تُخطّيا بنظافة. openclaw-local=Up (تيليجرام معطّل، صفر تعارض). redis-arsenal healthy.
- النسخة النهائية = v9. نسخة DR على لابتوب د. وائل مكتملة ومختبَرة E2E: تحديث R2 تزايدي (restic) + تشغيل مجموعات [1/2/3] + أكاديمي [4/5] + حماية التوكن (overlay) + self-heal شبكات/حاويات + تخطّي غير المتوافق + دماغ openclaw صامت (يُفعّل بقلب enabled=true عند تعطّل السيرفر).
- رحلة الإصلاح: v6 (restic include/exclude) → v7 (ترتيب ملّاك الشبكات + net self-heal) → v8 (تعارض شبكة المالك + inline errors) → v9 (default-address-pools في Docker Desktop UI + container self-heal + SKIP_LAPTOP + telegram off).
✅ ترقية نواة OpenClaw على اللابتوب (2026-07-20 06:36):
- سؤال د. وائل: لماذا اللابتوب على 2026.6.11 بينما السيرفر (والأصل) على 2026.7.1-2 رغم [6] Update from R2؟
- الجواب المؤكّد (مصادر حيّة): [6] Update from R2 = مزامنة بيانات/إعدادات/ذاكرة/skills فقط، لا يرقّي النواة. السبب: كلا سكربتَي النسخ (
full_server_backup.sh+full_server_secure_backup.sh) يستثنيان/node_modulesصراحةً (النواة 7.4GB في /data/.npm-global، قابلة لإعادة التوليد). دليل حاسم: استعادة [6] كتبت 53.9KiB فقط (لا مئات MB). السيرفر رُقّي 2026-07-19 17:25. - اللابتوب: PREFIX=/data/.npm-global (على الـ volume، دائم)، WHICH=/data/.npm-global/bin/openclaw، الإصدار كان 2026.6.11.
- الترقية:
docker exec openclaw-local npm install -g openclaw@2026.7.1-2 && docker restart openclaw-local→ NEWVER=2026.7.1-2 (0790d9f) — مطابق للسيرفر. (28s، تحذيرات allow-scripts حميدة.) - درس/قاعدة دائمة: [6] = data sync. ترقية النواة = خطوة منفصلة صريحة (
npm install -g openclaw@<version>داخل الحاوية، إصدار محدّد لاnpm update -g). تُطبَّق عند صدور إصدار جديد على السيرفر لمطابقة اللابتوب. - المشروع مكتمل 100%: 48 حاوية GREEN + إصدار مطابق + DR جاهز.
📋 خطة الترسانة المحلية — التوصيات النهائية (2026-07-20 07:05):
- الوثيقة:
projects/laptop-arsenal/MASTER_PLAN_LOCAL.md(أُرسلت msg 29994). - الرؤية: المحلي = عقدة متوازية متخصّصة (DR + خصوصية + Academy غير مقيّد بنموذج محلي + استغلال عتاد اللابتوب GPD Win Max 2: NPU/Radeon 890M/64GB)، ليس مجرد DR mirror. الحيّ يبقى المرجع الأساسي.
- قرارات: (1) مزامنة أحادية الاتجاه حيّ←محلي كل 3 أيام عبر [6] R2 مجدولة (Task Scheduler) — أأمن من syncthing المباشر على بيانات openclaw الحيّة. (2) بوت تيليجرام ثانٍ منفصل (BotFather) — أفضل من re-enable الطارئ. (3) Portal محلي بروابط localhost. (4) استغلال العتاد + نموذج محلي Qwen~32B uncensored لـ Academy (بصدق: NPU XDNA دعمه ناشئ؛ المكسب = خصوصية+غير مقيّد+offline). (5) أيقونة رابعة + إشعار إقلاع + فحص إصدار تلقائي + جدولة.
- 🔒 متطلب صارم د. وائل: المزامنة تنقل كل شيء إلا هوية تيليجرام (توكن+allowFrom+enabled) — البوت المحلي منفصل 100%، صفر تعارض. مضمون عبر: overlay يحفظ هوية تيليجرام (سأوسّعه ليحمي enabled أيضاً) + الأيقونات/اللانشر خارج شجرة /docker (لا تُمَسّ بالمزامنة) + Portal محمي + [6] فيه تحقّق JSON + rollback + health (لا انهيار).
- فحص إصدار للتطابق مع الحيّ: الحيّ يكتب إصداره في
memory/live_openclaw_version.txt(يُنسَخ R2) → المحلي يثبّت نفس إصدار الحيّ بالضبط بعد [6] (لا npm-latest). - ⏳ منتظر من د. وائل (3 مدخلات): (1) مخرجات docker ps المنافذ (لبناء Portal) (2) توكن البوت الثاني (3) ollama list على اللابتوب. البدء المقترح: المرحلة 1 (إصلاحات threadfin/syncthing/daemon + Portal + أيقونات) فور وصول المنافذ.
- أوامر أُرسلت بانتظار تشغيل د. وائل: fix_threadfin + حصر المنافذ (docker ps) + (سابقاً) الأيقونات (نجحت).
🧠 مراجعة الصباح — تنفيذ (11:38–11:55)
- uncensored.com: السبب الجذري = موجود في liberation_router Tier0 لكن غائب عن cron النشرة + capabilities_watch. أُضيف للاثنين. فحص حي: 71 models؛ Gemini 3.1 Pro/DeepSeek V4/R1 ✅؛ academic_readiness RC=0 وكل المزودين HTTP 200.
- Ollama: رُقّي 0.24.0 → 0.32.1؛ backup كامل
/data/.local/ollama-install.backup-0.24.0-20260720. API+5 models+توليد OLLAMA_OK نجح. خلل trap أثناء swap عولج فوراً قبل التسليم. - Unified Brain: تقرير
projects/unified-brain/ARCHITECTURE_REVIEW.md. القرار = Thin Facade جديد فوق الخدمات القائمة، لا monolith؛ shadow→canary→promote، rollback بإزالة route واحد. - MCP Generator: حُدّد كـ Postman MCP Generator (لا OpenAI generator). POC معزول APS+Paperclip نجح 6 tools. رُفض Postman SaaS للإنتاج واعتمد النمط المحلي؛ سُجل
mcp-aps-paperclipفي mcporter وlist/call نجح. لا تعديلات على تكاملات APS/Paperclip الأصلية.
🔒 دروس دائمة موحّدة — قواعد ذهبية لأي مستقبل (append pre-compact 2026-07-20 12:13)
🐳 Docker Desktop على WSL — 5 مصائد جوهرية
1. 🌙 Resource Saver mode = السبب الجذري لسلسلة انهيارات صامتة. أيقونة الهلال = المحرّك نائم بعد خمول →docker يختفي من WSL + docker ps يرجع فارغاً بلا خطأ + «WSL integration failed». ليست مشكلة إعداد. أول ما أرى «docker not found» أو WSL integration فيصل → أطلب من د. وائل يفحص أيقونة الحوت (هلال 🌙 أم أخضر ثابت 🐳)، لا أخمّن. الحل الدائم: Settings → Resources → Advanced → Resource Saver: OFF.
2. /etc/docker/daemon.json داخل kali يُتجاهَل تماماً. المحرّك الحقيقي في توزيعة docker-desktop منفصلة. التوسيع الوحيد الفعّال = واجهة Docker Desktop: Settings → Docker Engine → JSON → Apply & Restart. لا service docker restart (لا service داخل kali).
3. default-address-pools إلزامي عند >~30 ستاك. الافتراضي = 172.17-31/16 ~31 شبكة فقط → «all predefined address pools fully subnetted». الحل المُثبَت: {"default-address-pools":[{"base":"10.210.0.0/16","size":24},{"base":"10.211.0.0/16","size":24}]} = 512 شبكة. التحقق: docker network create _t && docker network inspect _t | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+" → المتوقع 10.210.x.0/24.
4. «Apply & Restart» يُنفّذ wsl --shutdown. التوزيعات المستخدمة تعلّق (Running ظاهرياً، لا تنفّذ). الحل: wsl --terminate kali-linux; wsl -d kali-linux -- echo KALI_ALIVE. تحذير Failed to start systemd user session عند العودة = حميد.
5. ديالوجات WSL integration لتوزيعات أخرى (مثل Ubuntu-24.04) لا تخصّنا. الاختيار الآمن = Skip WSL distro integration لا Restart (يمنع دورة wsl --shutdown جديدة).📦 restic — قواعد سلامة
--includeو--excludemutually exclusive — دمجهما يفشل فوراً (Fatal: exclude and include patterns are mutually exclusive). لتحذيرات symlinks الحميدة، الحل = معيار نجاح متين (JSON valid check + Restored count) لا--excludeإضافي.ignoring error ... directory not emptyعند symlinks-turned-real-dirs = تحذير حميد (رأينا 20 حالة). الاستعادة الفعلية تنجح (76483/76502 = 99.97%).
🕸️ Compose network dependencies — 3 حالات self-heal معتمدة
- Case A (v7): شبكة خارجية مفقودة (
X_default declared as external, but could not be found) →docker network createبالاسم المطلوب. - Case B (v8): شبكة متعارضة (خدمة أنشأتها بلا labels قبل صاحبها) →
docker network rmقبل إعادةup. - Case C (v9): اسم حاوية عالق (
container name "/X" is already in use) →docker rm -fقبل إعادةup. - الترتيب الصحيح: ملّاك الشبكات المشتركة (openclaw-4x4t + redis-arsenal + traefik + bot-proxy) يبدؤون أولاً، ثم المستهلكون.
🌐 Portal المحلي — نمط تصميم دائم
- جوهر الفرق عن الحيّ: النطاقات (
invest.drwaelalkishawi.com...) تشير للسيرفر لا للّابتوب → على المحلي الوصول =localhost:PORT. - البناء الصحيح: compose overrides محلية (
docker-compose.override.ymlلكل ستاك) تنشر منافذ 127.0.0.1:PORT، لا تعديل ملفات base (تحفظها المزامنة الأحادية). - جدول المنافذ المخصّصة (ثابت، مثبّت في setup_local_portal.sh):
- السكربت الجاهز:
projects/laptop-arsenal/local-image/setup_local_portal.sh(idempotent، ينشئ overrides + يعيد التشغيل + يولّد HTML ثنائي اللغة + ينسخه لسطح مكتب ويندوز عبرwslpath+ كشف تلقائي لـ Desktop/OneDrive Desktop).
💻 قواعد تفاعل PowerShell↔WSL (خط أحمر)
- قوالب Go
{{...}}تنكسر في PowerShell (يفسّرها كـ script blocks) → استخدمgrep/awkبدلاً منها، أو JSON output. - متغيرات bash المُسنَدة داخل
wsl -- bash -c "..."من PowerShell قد ترجع فارغة (بينما env vars مثل$HOMEتعمل) → استخدم مسارات حرفية كاملة دائماً، صفر$var، صفر$(cmd)، صفر backup names بـ$(date). - Heredoc عبر PowerShell لا يعمل موثوقاً → اكتب السكربت لملف عبر write ثم شغّله بأمر واحد.
- الاقتباس: أوامر PowerShell → WSL يجب أن تستخدم اقتباساً مفرداً
'...'للحفاظ على$و2>/dev/null(وإلا PowerShell يُفسدها).
🤖 تعطيل تيليجرام على اللابتوب (M-ready — DR mirror pattern)
- السبب: بوت اللابتوب يشارك نفس التوكن مع بوت السيرفر → getUpdates conflict + خطر أوامر مزدوجة على أجهزة د. وائل.
- الحل الجراحي:
jq '.channels.telegram.enabled=false' openclaw.json+ backup ثابت الاسم (openclaw.json.telegram-off.bak). التوكن يبقى (للطوارئ)، لكن البوت لا يستهلك getUpdates. - التفعيل الطارئ:
jq '.channels.telegram.enabled=true' + docker restart openclaw-local. - الحل الأمثل الدائم (طلب د. وائل، MASTER_PLAN المرحلة 2): بوت ثانٍ منفصل من BotFather بتوكن مختلف → صفر تعارض إطلاقاً + عمل بالتوازي. overlay يحفظ توكن+allowFrom+enabled عبر كل تحديث [6].
🚫 قاعدة سلوكية M-076 (مؤكّدة، سجّلها فوراً)
- صفر قتل exec يدوي. كل exec تشخيصي يجب أن يخرج بـ 0 (
|| true/; :/timeout N ... || true). أي إشعار «Exec failed» أحمر يخيف د. وائل وينافي عهد «صفر إزعاج بصري». - صفر
pkill -f/pgrep -fبنمط يطابق الأمر نفسه (self-match → إشعار فشل). اقتل بـ PID الرقمي المحدّد فقط، أو bracket-grep[c]loudflared. - تكرر اليوم: قتلي عملية find يدوياً تسرّب إشعار «Process: tide-sable failed». والأمر الثاني v5 exec failed بسبب heredoc quote conflict. القاعدة: أي أمر ممتد أو حلقة → لفّها بصمت تام + timeout داخل الأمر.
🎨 الأيقونات (نجحت وأثبتت النمط)
- 3 أيقونات على سطح المكتب أُنشئت بـ PowerShell +
WScript.ShellCOM +shell32.dllicons:
- النمط: التسمية الرباعية القادمة (Arsenal UPDATE R2 + Local Portal) نفس التقنية.
- جوهر المرونة:
arsenal.shيدعم CLI args (whole / stop-all / update / status / menu) — أي إجراء = أيقونة.
🧠 قرارات الترسانة الأربعة (2026-07-20، مسجّلة في تقارير مستقلّة)
1. Unified Brain (brain.drwaelalkishawi.com): يُبنى كـ Thin Facade (خيار B) فوق الخدمات القائمة، لا monolith. النشر Shadow → Canary(basicauth) → Promote. Rollback = إزالة موجّه Traefik واحد. القيود الصلبة: صفر مساس، صفر توقّف، تراجع فوري. تقرير: projects/unified-brain/ARCHITECTURE_REVIEW.md.
2. uncensored.com: السبب الجذري لغيابه من النشرة = موجود في liberation_router.py Tier0 لكن غائب عن cron النشرة + capabilities_watch.py. أُصلحت الطبقتان. فحص حي: 71 نموذجاً، Gemini 3.1 Pro + DeepSeek V4 + DeepSeek R1 ✅. قاعدة دائمة: أي مزوّد جديد يجب تحديث 4 طبقات ذرياً: route + capabilities watcher + newsletter watcher + readiness check.
3. Ollama: رُقّي 0.24.0 → 0.32.1، backup محفوظ، API+5 نماذج+توليد OLLAMA_OK نجح. النماذج في /data/.ollama لم تُمَس.
4. Postman MCP Generator: ✅ اعتُمد النمط المحلي (Python MCP SDK يغلّف CLIs القائمة عبر subprocess، read-only، صفر تعديل)، ❌ رُفض Postman SaaS للإنتاج الحساس (رفع specs للسحابة). POC نجح: 6 tools، compile+list+call. سُجّل mcp-aps-paperclip في mcporter. projects/mcpgen-poc/REPORT.md.
5. Qwen: الاسم الرسمي المؤكّد = Qwen3.6-Max-Preview (proprietary، لا أوزان مفتوحة). watchlist فقط حتى GA/أوزان + benchmark مقارنة قبل أي إدخال للسلسلة.🚀 الحالة النهائية (04:24-06:36 GMT+3)
- ✅ 48 حاوية GREEN
- ✅ OpenClaw 2026.7.1-2 (0790d9f) مطابق للسيرفر
- ✅ 3 أيقونات سطح مكتب تعمل
- ✅ threadfin مصلح (
latestبدل 0.5.0 المحذوف) - ✅ تيليجرام DR معطّل (صفر تعارض)
- ⏳ Portal + syncthing (
syncthing/syncthingالرسمية) + daemon.json cleanup + بوت ثانٍ + جدولة R2 كل 3 أيام + استغلال العتاد/النموذج المحلي: منتظرة استئناف د. وائل بعد نقاش الترسانة المحلية (MASTER_PLAN)
🔴 WhatsApp توقّف اليوم — session conflict من نسخة اللابتوب DR (2026-07-20 15:20):
- العرض: د. وائل: واتساب كان يعمل للأمس ثم توقّف فجأة اليوم.
- السبب الجذري (بدليل السجل الحرفي — لا تخمين): 05:20 اليوم =
WhatsApp Web connection closed (status 440: session conflict)ثمCleared WhatsApp Web credentials. مجلد/data/.openclaw/credentials/whatsapp/أصبح فارغاً (لا creds.json). - الآلية: نسخة اللابتوب DR (
openclaw-local) اشتغلت اليوم بنفس أوراق اعتماد جلسة WhatsApp المستعادة من R2 → جهازان على نفس ربط WhatsApp Web → تعارض 440 → طرد متبادل + مسح ربط السيرفر. - الخطأ الجذري مني: أمس عطّلت تيليجرام على اللابتوب (getUpdates conflict) لكن نسيت واتساب — وهو أيضاً قناة بأوراق اعتماد مشتركة تتعارض بنفس الطريقة.
- الإصلاح (جزءان): (1) اللابتوب:
jq .channels.whatsapp.enabled=false+ restart (أُرسل الأمر لد. وائل عبر tg_code.sh). (2) السيرفر: إعادة ربط QR عبرwhatsapp_login start --account default --force(يُرسل عند جاهزية د. وائل، QR ينتهي بثوانٍ). - الإصلاح الدائم (مُطبَّق):
arsenal.sh apply_overlayالآن يفرضenabled=falseعلى telegram + whatsapp بعد كل تحديث [6] — نسخة DR لا تشغّل أي قناة حيّة بأوراق مشتركة أبداً. bash -n OK. - 🔴 قاعدة دائمة (DR mirror): أي نسخة DR مستعادة من R2 يجب أن تُعطّل كل القنوات ذات الأوراق المشتركة (telegram + whatsapp + أي قناة session-based)، ليس تيليجرام فقط. القنوات الحيّة على نسخة واحدة فقط (السيرفر) في أي لحظة.
📋 المرجع الكامل للنسخة المحلية
projects/laptop-arsenal/MASTER_PLAN_LOCAL.md— التوصيات النهائية الموحّدة (بوت ثانٍ + مزامنة أحادية + Portal + استغلال العتاد + 5 مراحل تنفيذ).projects/laptop-arsenal/local-image/arsenal.shv10 — اللانشر مع self-heal (Cases A/B/C) + probe.projects/laptop-arsenal/local-image/setup_local_portal.sh— بناء Portal (جاهز، ينتظر تشغيل د. وائل).reports/MORNING_REVIEW_FINAL_2026-07-20.md— مراجعة الصباح التنفيذية.projects/unified-brain/ARCHITECTURE_REVIEW.md— تقرير بوابة الدماغ الموحّدة.projects/mcpgen-poc/REPORT.md— تقييم MCP Generator + POC.
🧠 Unified Brain — Phase 0+1 بُنيت واختُبرت حياً فعلاً (append pre-compact 2026-07-20 16:19)
- Phase 0 (gateway):
projects/unified-brain/gateway.pyيعمل على127.0.0.1:8909فقط (loopback، صفر تسرّب خارجي مؤكّد بفحص). يغلّفbrain.pyالقائم./healthيظهر 6 محركات مصرّحة: direct · ask_deep · council · liberation · capability · tender. commander=google/gemini-3.1-pro-preview، deep=anthropic/claude-opus-4-8. - ⚠️ منفذ 8908 مشغول بـ obsidian-viewer (PID 1352،
projects/obsidian-viewer/app.py) — لذا نُقلت بوابة الدماغ إلى 8909 (صفر مساس بـ obsidian-viewer، احتراماً لقيد Phase 0 «صفر مساس»). حارس keepalive أُضيف للدماغ (نفس نمط obsidian-viewer في daemons_keepalive.sh). - كل endpoints مختبرة حياً:
/health✅ ·/analyze(heuristic 1ms + LLM) ✅ ·/runinline ✅ ·/jobsbackground (auto-promote للطويل، job8a17ff5fb39dاكتمل بجودة كاملة) ✅. - Phase 1 Shadow (
projects/unified-brain/shadow_run.py): 12 طلب تمثيلي عبر/analyzeفقط (قرار توجيه، صفر تنفيذ/تقديم نتائج). النتيجة PASS 12/12. التوزيع: direct=4 · capability=2 · ask_deep=3 · council=1 · liberation=2. المجالات: general=5 · engineering=2 · economic=2 · science=1 · cyber=1 · medical=1. p50≈7s، heuristics=1ms. - أهم نتيجة أمنية: ✅ كل الطلبات الحسّاسة (SQL injection تعليمي + جرعات طبية) وُجِّهت صحيحاً إلى
liberation(2/2) — لا يمرّ حسّاس عبر مسار قد يُرفَض. - الحالة: Phase 0+1 مكتمل ومختبَر. Phase 2 (Canary على
brain.drwaelalkishawi.comخلف basicauth+cf-only) = لاحقاً بموافقة د. وائل. Rollback = إزالة موجّه Traefik واحد. - تقرير المقارنة النهائي:
reports/SERVER_WORK_COMPLETE_2026-07-20.md.
🌐 البوابة الرئيسية — فحص انحراف (2026-07-20 ~15:30)
- 31 خدمة، كل الروابط حيّة، صفر انحراف (لا subdomain ميت، لا خدمة ناقصة).
- قرار مهني: أعمال اليوم (unified-brain loopback + mcp-aps-paperclip + إصلاح uncensored + ترقية Ollama) كلها بنية داخلية، ليست صفحات ويب جديدة → لا تحتاج بطاقات بوابة. البوابة سليمة كما هي.
- ARSENAL_INDEX حُدّث: 16 MCP (كان 15) بإضافة
mcp-aps-paperclip، + unified-brain + uncensored + Ollama 0.32.1.
🔴 WhatsApp — استُعيد من backup بلا QR + لغز الـ group (تحديث نهائي 2026-07-20 16:19)
- الاستعادة (نجحت): بدل انتظار الموبايل الثاني (الغائب)، وُجدت نسخة جلسة احتياطية على السيرفر (
preupgrade_2237) واستُعيدت. النتيجة الحيّة (15:41): كلا الحسابين اتصلا —[bot] starting provider (+96565830235)+[default] starting provider (+96599662183)+Listening for WhatsApp inbound+ صفر loggedOut/440 بعد الاستعادة + creds PRESENT. - ⚠️ تصحيح مهم: OpenClaw نفسه مسح بيانات الربط تلقائياً عند اكتشاف التعارض 440 (
Cleared WhatsApp Web credentials) — لم يحذفها أحد يدوياً. المسح كان نتيجة التعارض لا سببه. - لغز «typing بلا رد» في الـ group (سلوكي لا عطل): البوت يستقبل ويعالج رسائل د. وائل بالنموذج فعلاً، لكن النموذج يقرر حرفياً
"No actionable request here"→ NO_REPLY → typing ثم صمت. ليس شللاً. - السبب الأرجح: حساب البوت مربوط على رقم د. وائل نفسه (96565830235)؛ حين يرسل من رقمه في الـ group، البوت يرى الرسالة صادرة «منه هو» (fromMe) فلا يرد على نفسه. سابقاً «كان يعمل» لأن العضو الآخر (الموبايل الثاني 96599662183) هو من يرسل.
- ⏳ منتظر من د. وائل: توضيح الغرض من الـ group (هل يريد البوت يرد على رسائله هو فيه رغم أن رقمه = رقم البوت؟) لضبط الإعداد. + اختبار حاسم: رسالة من رقم آخر في الـ group، أو رسالة فيها طلب صريح.
💻 تقنية base64 لأوامر PowerShell→WSL→bash (خط أحمر جديد مُثبَت)
- المشكلة: تعدّد طبقات الاقتباس (PowerShell ثم
wsl -- bash -lcثم jq filter) يُفسد أي رمز خاص (.,",$,=) → أخطاء مثل=false ...: No such file or directory. حتى الاقتباس الحرفي الكامل فشل بسببjqfilter داخل طبقتين. - الحل النهائي المُثبَت (نجح فوراً): اكتب سكربت bash كاملاً ثم
base64encode ثم أرسله كـecho '<b64>' | base64 -d | bash. لا رمز خاص يمرّ عبر الطبقات إطلاقاً. أعطىWA_ENABLED_NOW=false+WA_DISABLED_OKمن أول مرة. - القاعدة الدائمة: أي أمر WSL معقّد (فيه jq/quotes/redirects) يُلصَق في PowerShell → غلّفه بـ base64. أبسط وأمتن من محاولة تهريب الاقتباسات عبر 3 طبقات.