لا يتعلق الأمر في «Codex vs Claude Code» بتحديد فائز واحد شامل بقدر ما يتعلق باختيار أسلوب العمل الذي يمكنك الوثوق به يوميًا. يمكن لكلا المنتجين فحص مستودع، وتحرير ملفات متعددة، وتشغيل الأوامر، وإجراء الاختبارات، وشرح التصحيح. وتكمن الاختلافات الجوهرية في كيفية تفويض المهام، ومدى تكرار توجيه الوكيل، وحجم الأدلة التي يمكنك فحصها، ومدى ملاءمة كل أداة لبيئة التطوير الحالية لديك.
في اختبارنا الخاضع للرقابة على مستودع المهام الأربع، سجل «كوديكس» 98/100، بينما سجل «Claude Code» 99/100. وقد أنجز كلاهما المهام الأساسية. أظهر Claude Code تغطية أوسع للمراجعة والحالات الحدية، في حين أن Codex غالبًا ما توصل إلى النتيجة المطلوبة بنطاق أضيق وقدم أدلة أقوى على مستوى التشغيل في إعداداتنا. ولا يُعد فارق نقطة واحدة في اختبار صغير بلغة Python سببًا كافيًا لإعلان فائز عالمي.
يمكن للمطورين الذين لا يرغبون في ربط بقية سير عملهم بوكيل برمجة واحد إضافة GlobalGPT كطبقة منفصلة متعددة النماذج ومتعددة الوسائط. تدمج GlobalGPT أكثر من 100 نموذج من أفضل النماذج، مثل GPT 5.6 وClaude Opus 5 وGPT Image 2، في لوحة تحكم واحدة. علاوة على ذلك، فإن GlobalGPT CLI, ، ويمكن استخدام مسارات MCP وSkill من Codex أو Claude Code للحصول على آراء ثانية أو للتخطيط أو التوثيق أو أي نماذج أخرى مدعومة، بينما يحتفظ مضيف البرمجة الأصلي بالسيطرة على تعديلات المستودع والاختبارات.

تجمع هذه المقارنة بين المعلومات الرسمية المتعلقة بالخطط، والأعمال العملية المتعلقة بالمستودعات، والمخرجات الكاملة القابلة للتوسيع، والتجارب المجتمعية المحددة بوضوح. والهدف من ذلك هو مساعدة المطور المستقل على اختيار أداة البرمجة الأساسية دون التعرض للارتباك الناجم عن طرق الوصول عبر الاشتراكات، والرصيد الإضافي، وفواتير واجهة برمجة التطبيقات (API).
نظرة سريعة على كود «Codex» مقابل كود «Claude»
| العامل الحاسم | كودكس | كلود كود |
|---|---|---|
| الأعمال الأساسية المتعلقة بالمستودع | يقوم بقراءة المحتوى وتحريره وتنفيذ الأوامر والتحقق من التغييرات عبر أسطح Codex المدعومة | وكيل طرفي تفاعلي مخصص للقراءة والتحرير وتنفيذ الأوامر والتحقق من التغييرات |
| النمط الذي لوحظ في اختبارنا | أكثر إيجازًا في بعض جوانب التنفيذ وإصلاح الأخطاء | أكثر شمولاً في تحليل المستودعات، والاختبارات، ونطاق المراجعة |
| فهم المستودع | الارتباط الوظيفي بالمهمة المتوقفة | |
| مراجعة الكود | تم اكتشاف وإصلاح عيبين صحيحين من فئة الخطورة العالية | أبلغ عن المزيد من المشكلات القابلة للتكرار، وقاد الفريق من 19/20 إلى 18/20 |
| السرعة المقاسة | متباينة؛ لم تكن الظروف متكافئة بما يكفي لتحديد فائز عام | |
| الفئة المخصصة للمستهلكين المبتدئين | $20 شهريًّا من خلال الخطة ذات الصلة ChatGPT | Claude Pro: $20 شهريًّا في الولايات المتحدة |
| فئات الاستخدام الأعلى | فئتا $100 و$200 | بحد أقصى 5x عند $100 وبحد أقصى 20x عند $200 |
يصف هذا الجدول قرار شراء، وليس قائمة ترتيب للنماذج. وقد تؤدي أي تغييرات في إعدادات النموذج أو المستودع أو تكوين الأذونات أو مواصفات المهمة إلى تغيير النتيجة. إذا كنت تستخدم أحد المنتجات بالفعل، فإن أفضل مقارنة هي إجراء مهمة محدودة النطاق من قاعدة الكود الخاصة بك باستخدام نفس أمر النجاح وبدون إعادة محاولات لتحسين الجودة.
ملف تعريف الاختبار الخاضع للرقابة
أول نتيجة صحيحة، بنفس معايير التقييم الثابتة. تم توحيد القيم الموضحة في الأشرطة وفقًا للدرجة القصوى لكل مهمة.
يوضح الرسم البياني مصدر هذا الفارق بنقطة واحدة؛ وهو لا يحول مباراة صغيرة إلى تصنيف شامل.
ما هو «كوديكس» و«كود Claude» في الواقع؟
يُعد كل من «Codex» و«Claude Code» منتجين من منتجات الوكيل، وليسا مجرد أسماء طرازات. الأساسي نموذج الذكاء الاصطناعي للبرمجة هذا أمر مهم، لكن «الهيكل» المحيط به يحدد أيضًا الملفات التي يمكن للوكيل الاطلاع عليها، والأوامر التي يجوز له تنفيذها، وكيفية عمل عمليات الموافقة، وكيفية الاحتفاظ بالسياق، والأدلة التي تبقى بعد انتهاء المهمة. إن الاكتفاء بمقارنة سمعة النموذج فقط يتجاهل جزءًا كبيرًا من التجربة التي يشتريها المطور.
يغطي «Codex» سير العمل عبر سطر الأوامر، وبيئة التطوير المتكاملة (IDE)، وأجهزة سطح المكتب، والسحابة. وهذا التنوع يجعله مناسبًا لكل من التعاون المحلي المباشر والتفويض الأكثر تحديدًا. أما «Claude Code» فيتمحور حول سير عمل محوري قائم على الحوار مع تكاملات مدعومة وإمكانيات تخصيص واسعة؛ وهذا دليل استخدام Claude في البرمجة يقدم هذا مقال مقدمة أوسع نطاقاً عن مسار العمل هذا. بالنسبة لبعض المطورين، فإن مشاهدة أحد الوكلاء وهو يعمل في محطة العمل يبعث على الطمأنينة. أما بالنسبة لآخرين، فإن العناصر المهمة هي الفروق النهائية والاختبارات وسجل التدقيق، وليس الحوار المستمر.
كما يفسر هذا التمييز سبب اختلاف سلوك اختبارين يستخدمان نماذج قوية نظريًّا. فالمضيف هو الذي يقرر كيفية عرض التعليمات، وكيفية استدعاء الأدوات، ومتى يتعين على الإنسان الموافقة على إجراء ما. وقد تؤدي المقارنات المجتمعية التي تتجاهل «نظام التحكم» إلى الخلط بين السلوك على مستوى المنتج والحقيقة على مستوى النموذج.
- النموذج توفر القدرة على الاستدلال والتوليد.
- مجموعة أسلاك التوصيل الخاصة بالوكيل يتحكم في الملفات والأوامر والسياق والموافقات وعمليات الاستعادة.
- عقد مهمة المستخدم يحدد النطاق، واختبارات النجاح، والوقت الذي ينبغي أن يتوقف فيه الوكيل.

سير العمل والتحكم: التفويض أم التوجيه المستمر؟
غالبًا ما يكون السؤال الأكثر فائدة بشأن مقارنة Codex و Claude ليس “أيهما يكتب كودًا أفضل؟” بل “كيف أرغب في العمل به؟” يمكن تفويض مهمة واضحة ومحددة بهدف دقيق ونطاق مسموح به وأمر للتحقق. أما عملية إعادة الهيكلة الغامضة فتستفيد من المناقشة والتدقيق المرحلي وفرصة إعادة توجيه المنفذ قبل أن يحدث تغييرًا كبيرًا.
يُعد التوجيه المستمر أمراً مفيداً عندما تكون المتطلبات قيد التطور أو عندما لا تزال التقييمات المتعلقة بالبنية قيد المناقشة. ويصبح ذلك عبئاً عندما يطلب الوكيل مراراً وتكراراً اتخاذ قرارات كان من الممكن حلها بالاستناد إلى التعليمات الموجودة في المستودع. ويُعد التنفيذ الذاتي أمراً مفيداً عندما يكون عقد المهمة مستقراً. ويصبح ذلك محفوفاً بالمخاطر عندما يضع الوكيل افتراضات غير مدققة أو يوسع نطاق المهمة دون وجود مسار واضح للرجوع إلى الحالة السابقة.
وصف تقرير مفصل نُشر على موقع Reddit بتاريخ 13 أبريل 2026 قضاء ما يقارب 100 ساعة في استخدام Claude Code و20 ساعة في استخدام Codex، وذلك في مشروع يضم حوالي 80,000 سطر من لغتي Python وTypeScript مع ما يقارب 2,800 اختبار. وصف المؤلف أسلوب Claude بأنه أسرع وأكثر تفاعلية ولكنه يحتاج إلى مزيد من المتابعة، ووصف أسلوب Codex بأنه أبطأ وأكثر تروياً. ويُعد هذا التقرير مفيداً بشكل غير عادي لأنه يتضمن سياق المشروع والتجربة، لكنه لا يزال يمثل سير عمل مطور واحد فقط.

لم تُظهر نتائج قياساتنا فائزًا واضحًا. فقد أنجز «Claude» المهمتين الأوليين بسرعة أكبر، بينما أنجز «Codex» المهمتين الأخيرتين بسرعة أكبر. كما استخدم «Claude» وكيلًا فرعيًّا كحل بديل بعد أن أصبح مسار المصادقة عبر واجهة سطر الأوامر (CLI) غير متاح، لذا لم تكن مسارات التنفيذ متطابقة مع تلك التي أجريت في المختبر. والاستنتاج المنطقي هو أن السرعة تعتمد على المهمة، والنموذج المختار، وإعدادات الجهد، والسياق، والمضيف — وليس أن أيًا من المنتجين أسرع دائمًا.
فهم المستودع وإدارة السياق
إن فهم المستودع لا يقتصر على تسمية المجلدات فحسب. فالوكيل الفعال يجب أن يتتبع كيفية انتقال البيانات بين الملفات، ويحدد العقود التي تقيّد أي تغيير، ويحدد موقع الاختبارات، ويميز بين الأعراض ومصدرها المحتمل، ويشرح مخاطر تعديل الطبقة الخاطئة. فخريطة شاملة يمكن أن تكشف عن التناقضات الخفية؛ في حين أن الخريطة الموجزة يمكن أن تساعد المطور على التوصل إلى قرار تنفيذ آمن بشكل أسرع.
في مهمة T1 الخاصة بنا المخصصة للقراءة فقط، حصل كلا الوكيلين على 20/20 واستندت إجاباتهما إلى المستودع. كان أسلوب «Claude Code» أكثر شمولية وكشف عن تناقضات إضافية في العقود. أما أسلوب «Codex» فكان أكثر إيجازًا مع استمراره في تحديد الملفات ذات الصلة والمخاطر وخطة التنفيذ. ولا يُعتبر أي من الأسلوبين متفوقًا تلقائيًّا. تساعد الشمولية في عمليات الترحيل والتدقيق غير المألوفة؛ بينما تساعد الإيجازية عندما يكون المطور على دراية بالبنية بالفعل ويرغب في خطة تغيير مركزة.
T1 · اختبار المستودع الخاضع للرقابة
افهم محتوى المستودع غير المألوف قبل إجراء أي تغييرات عليه
تحديد بنية الخريطة، وتتبع تدفق البيانات، وتحديد المخاطر المتعلقة بالميزات ذات الأولوية، وعدم إجراء أي تغييرات على الملفات.
الهندسة: النموذج، والمستودع، والخدمة، وأداة زمنية غير موصلة. المخاطر الرئيسية: دلالات الأولوية غير المحددة، والتوافق، والترتيب، والتحقق من الصحة، وعدم توافق النطاق.
رأي المراجع: موجز، ومستند إلى الملفات، وكافٍ لاتخاذ القرار المعلق.
ثلاث طبقات بالإضافة إلى وحدة مستقلة واحدة. لا توجد دورات؛ وحقن التبعية في أدنى حد ممكن. كما كشفت عن تخصيص المعرّفات، وعقود الأخطاء غير المتماثلة، وتغطية الاختبار المحدودة.
رأي المراجع: أكثر شمولاً مع الاستمرار في تلبية نفس شروط "القراءة فقط".
عرض الناتج الكامل لـ Codex
الإخراج الأول الصحيح والمُعقَّم بالكامل
## بنية النظام
هذه حزمة صغيرة لغة بايثون تعتمد على المكتبة القياسية فقط، وتتألف من أربع طبقات وظيفية:
- **نموذج البيانات:** [`Job`]() هي فئة بيانات غير قابلة للتغيير تحتوي على `identifier` و`name` و`owner`. تقوم `Job.to_dict()` بتسلسلها عبر `dataclasses.asdict()`.
- **المستودع:** [`JobRepository`]() يخزن المهام في قاموس داخل الذاكرة، حيث يتم استخدام المعرّف كمفتاح. لا توجد قاعدة بيانات أو تخزين دائم.
- **الخدمة:** [`SchedulerService`]() تتولى تخصيص المعرف، وتوحيد المدخلات، والإنشاء، والإدراج في القائمة، والحذف.
- **أداة الوقت:** [`next_daily_run()`]() تحسب وقت التشغيل التالي، لكن لا يوجد ما يستوردها أو يربطها بـ `Job` أو `SchedulerService` أو `JobRepository`.
- **واجهة برمجة التطبيقات العامة (API):** [`scheduler.__init__`]() تصدر `SchedulerService` فقط.
على الرغم من اسم المستودع، لا تحتوي المهام حاليًا على معلومات الجدولة، ولا توجد قائمة انتظار للتنفيذ. وبالتالي، يمكن أن تؤثر الأولوية على البيانات الوصفية المخزنة وترتيب القائمة، لكنها لا يمكن أن تؤثر على التنفيذ الفعلي للمهمة دون توسيع النظام بشكل كبير.
## تدفق بيانات الإنشاء والإدراج
الإنشاء من خلال `SchedulerService.create_job(name, owner)`:
1. [`create_job()`]() ترفض الأسماء المكونة من مسافات بيضاء فقط.
2. تقوم بقص `name` و`owner`، ثم تنشئ كائن `Job` غير قابل للتغيير باستخدام `_next_identifier` الخاص بالخدمة.
3. [`JobRepository.save()`]() تكتب الكائن إلى `_jobs[job.identifier]`.
4. تقوم الخدمة بزيادة قيمة `_next_identifier` وتُرجع نفس كائن `Job`.
عرض قائمة المهام عبر `SchedulerService.list_jobs()`:
1. [`list_jobs()`]() تفوض مباشرة إلى `repository.all()`.
2. [`JobRepository.all()`]() تقوم بفرز مفاتيح القاموس ترتيبًا رقميًّا.
3. وبالتالي، يتم إرجاع المهام بترتيب تصاعدي حسب المعرّف/تاريخ الإنشاء، وليس حسب الجدول الزمني أو الأولوية.
## الملفات التي من المحتمل أن تتأثر بأولويات المهام
مطلوب:
- [`scheduler/models.py`](): إضافة حقل الأولوية وأي قيمة افتراضية. ستقوم `to_dict()` بتضمينه تلقائيًا لأنها تستخدم `asdict()`.
- [`scheduler/service.py`](): قبول الأولوية والتحقق من صحتها وتمريرها إلى `Job`.
- [`tests/test_scheduler.py`](): تغطية السلوك الافتراضي، والصريح، وغير الصالح، والمسلسل، وترتيب الأولويات.
شروط:
- [`scheduler/repository.py`](): لا يتم تغيير `all()` إلا إذا كان المقصود من الأولويات التحكم في ترتيب القائمة. يجب أن يتولى مفتاح ثانوي حتمي مثل `identifier` معالجة حالات التعادل.
- [`scheduler/__init__.py`](): لا يتم التحديث إلا إذا أصبحت الأولوية قائمة عامة أو كائن قيمة.
- [`README.md`](): قم بتوثيق القيم المقبولة والقيمة الافتراضية ودلالات الترتيب.
من المحتمل ألا يتأثر:
- `scheduler/time_rules.py`، لأن الرمز الوحيد فيه يعمل على تاريخ ووقت محددين ولا علاقة له بالمهام أو الترتيب.
## المخاطر الرئيسية
- **دلالات غير محددة:** لا يقدم الكود أي سابقة تحدد ما إذا كانت القيم الأكبر أو الأصغر تعني أولوية أعلى، أو ما هي القيم الصالحة، أو ما إذا كانت الأولوية تؤثر على الترتيب في القائمة على الإطلاق.
- **التوافق:** إضافة وسيطة مطلوبة إلى `Job` أو `create_job()` من شأنها تعطيل المستدعين الحاليين مثل `create_job("Daily report", "Alex")` في الاختبار الحالي. ويحافظ القيمة الافتراضية على صلاحية هذا الاستدعاء.
- **خلل في المنشئ الموضعي:** يتم إنشاء `Job` حاليًا بشكل موضعي في `SchedulerService.create_job()`. قد يؤدي وضع الحقول والاستدعاءات الموضعية المستقبلية إلى تعيين قيم خاطئة دون إشعار؛ وسيكون الإنشاء باستخدام الكلمات المفتاحية أكثر أمانًا.
- **تغيير الترتيب:** يؤدي استبدال ترتيب المعرفات في `JobRepository.all()` إلى تغيير السلوك المعمول به. تحتاج الأولويات المتساوية إلى معيار فاصل ثابت.
- **الغموض في التحقق من الصحة:** قد تسمح قيمة Python غير المقيدة باستخدام سلاسل نصية أو قيم منطقية أو أعداد صحيحة عشوائية يصعب مقارنتها بشكل متسق.
- **عدم تطابق نطاق التنفيذ:** لا يوجد موزع أو قائمة انتظار للتشغيل. الادعاء بأن الأولوية تغير المهمة التي يتم تنفيذها أولاً لن يدعمه أي رمز حالي.
- **قيود الذاكرة:** تختفي الأولوية، مثل أي حقل آخر في المهمة، عند انتهاء العملية لأن `_jobs` هو مجرد قاموس مثيل.
## خطة التنفيذ والتحقق من الصحة
1. حدد العقد أولاً: التمثيل، والقيم المسموح بها، والقيمة الافتراضية، واتجاه الأولوية، وكيفية الفصل في حالة التعادل، وما إذا كانت الأولوية تغير ترتيب القائمة.
2. أضف `priority` إلى `Job`، ويفضل أن يكون ذلك بقيمة افتراضية متوافقة مع الإصدارات السابقة.
3. قم بتوسيع `SchedulerService.create_job()` بمعلمة أولوية افتراضية، وتحقق من صحتها، وقم بإنشاء `Job` باستخدام الحجج الكلمية.
4. إذا كان الترتيب يراعي الأولوية، فقم بتغيير `JobRepository.all()` لترتيب العناصر حسب الأولوية أولاً والمعرف ثانيًا. وإلا، اترك ترتيب المستودع دون تغيير.
5. أضف اختبارات لما يلي:
- إنشاء موجود بحجتين.
- الحفاظ الصريح على الأولوية.
- الأولوية الافتراضية.
- الأنواع غير الصالحة والقيم خارج النطاق.
- مخرجات `Job.to_dict()`.
- ترتيب القائمة في حالة وجود أولويات متعددة.
- الترتيب الثابت للأولويات المتساوية.
- السلوك الحالي للأسماء الفارغة.
6. قم بتحديث ملف README بالعقد العام الدقيق.
7. تشغيل مجموعة الاختبارات الكاملة دون اتصال بالإنترنت باستخدام `python3 -m unittest discover -s tests -v`.
## تم إجراء التحقق
- مجموعة الاختبارات الأساسية: **اجتياز اختبارين**.
- أكد البحث عن الرموز على نطاق المستودع أن `next_daily_run()` غير مرتبط ولا توجد رموز أولوية حالية.
- الملفات التي تم تغييرها: **لا شيء**.
- تنفيذ الميزة: **لم يتم**، كما هو مطلوب.
> **الخلاصة + القرار**
>
> التغيير بسيط إذا كانت الأولوية مجرد بيانات وصفية أو ترتيب في القائمة: بشكل أساسي `models.py` و`service.py` و`repository.py` والاختبارات. قبل التنفيذ، القرار المطلوب هو ما إذا كانت الأولوية تصف المهمة فحسب أم أنها تغير ترتيب `list_jobs()`، بالإضافة إلى مقياس القيمة والقيمة الافتراضية والاتجاه وقاعدة الفصل في حالة التعادل.عرض الناتج الكامل لرمز Claude
سجل التسليم الكامل، بما في ذلك النص الحرفي لأول ناتج صالح
سجل تشغيل # T1 — فهم مستودع غير مألوف
معلمات تنفيذ ##
| الحقل | القيمة |
| --- | --- |
| المهمة | `T1` |
| المطالبة المجمدة | `01-prompts/T1.md` |
| SHA-256 للموجه المجمد | `a571ff15c2502ec29b172ae2e77dd9ab0caca2869b91f9468d47571434d16c17` |
| وحدة التنفيذ | وكيل فرعي معزول Claude، `للأغراض العامة`، سياق جديد |
| طريقة العزل | **الرجوع إلى الوكيل الفرعي** (تخفيض الإصدار الموثق — انظر `results/isolation-decision.md`) |
| نسخة نظيفة مخصصة | `runtime/workspaces/T1` |
| إصدار كود Claude | `2.1.220` |
| إعداد النموذج | `claude-opus-5` |
| start_utc | `2026-07-28T10:27:31Z` |
| end_utc | `2026-07-28T10:28:32Z` |
| المدة | 61 ثانية (بالتزامن مع T2–T4؛ ليس قياسًا دقيقًا للزمن المستغرق) |
| رقم المحاولة | 1 |
| الحالة | `صالح` |
| تدخل بشري | لا شيء |
## ملخص أداة Safe
`date`، `find`، `ls`، `wc`، `stat`، `grep`، `Read` على 7 ملفات في مساحة العمل، `python3 -V`،
`python3 -m unittest discover -s tests -v`. جميع عمليات القراءة محصورة في مساحة العمل المخصصة.
لا شبكة، لا تثبيتات، لا عمليات كتابة.
## نتيجة الفحص دون اتصال بالإنترنت
`python3 -m unittest discover -s tests -v` → اختباران، OK (الخروج 0). أعيد التحقق من قبل
المنسق من خارج مساحة العمل: انظر `results/checks/T1-public.txt`.
## التصحيح
لا يوجد. ملف `results/T1/patch.diff` فارغ، و`diff -ru 02-fixture runtime/workspaces/T1`
لا يُظهر أي اختلافات. تطلبت المهمة الفحص دون تغيير الملفات؛ وهذا
تم تأكيده بدلاً من الافتراض.
## الأخطاء التي تم تصحيحها
خطأ واحد قابل للاسترداد في شل: استخدم أمر `grep` الأولي أنماط `--include=*.py` غير محاطة بعلامات اقتباس، والتي
حاولت شل توسيعها؛ أُعيد تشغيل الأمر باستخدام أنماط محاطة بعلامات اقتباس ونجح الأمر. لا يوجد تأثير على النتائج.
## المخرجات المرئية (حرفياً)
### 1. ما هو هذا المستودع
أداة ثابتة مستقلة تابعة لمكتبة Python القياسية باسم `local-scheduler-1.0.0` (`fixture-manifest.json`)، مرخصة بموجب ترخيص MIT، دون أي تبعيات شبكية أو إنتاجية (`README.md`، `"network_required": false`). وهو صغير جدًّا: 8 ملفات مصدر/وثائق بالإضافة إلى ملف البيان، بإجمالي 103 أسطر. المترجم الموجود هو **Python 3.9.6**. لا يوجد ملف `pyproject.toml`، أو `setup.py`، أو تكوين CI، أو أداة فحص الأخطاء البرمجية (linter)، أو تكوين أداة التحقق من الأنواع — وسير العمل الوحيد المعلن هو `python3 -m unittest discover -s tests -v` (`README.md`).
### 2. البنية
ثلاث طبقات بالإضافة إلى وحدة نمطية منفردة، جميعها ضمن `scheduler/`:
| الطبقة | الملف | الرمز | المسؤولية |
|---|---|---|---|
| واجهة الحزمة | `scheduler/__init__.py` | `__all__ = ["SchedulerService"]` | تعيد تصدير `SchedulerService` فقط؛ ولا تشكل `Job` و`JobRepository` و`time_rules` جزءًا من الواجهة العامة |
| نموذج المجال | `scheduler/models.py` | `Job` (`@dataclass(frozen=True)`) | كائن قيمة غير قابل للتغيير يحتوي على الحقول `identifier: int`، `name: str`، `owner: str`، بالإضافة إلى `to_dict()` المُنفَّذ كـ `asdict(self)` |
| الاستمرارية | `scheduler/repository.py` | `JobRepository` | `dict` في الذاكرة بمفاتيح تعريفية؛ `save`، `get`، `all`، `delete` |
| خدمة التطبيق | `scheduler/service.py` | `SchedulerService` | التحقق من الصحة، تخصيص المعرف، التنسيق: `create_job`، `list_jobs`، `delete_job` |
| يتيم | `scheduler/time_rules.py` | `next_daily_run` | حساب التكرار — **لا يستورده أي ملف** |
اتجاه التبعية واضح وأحادي الاتجاه: يستورد `service.py` من `.models` و`.repository`؛ ويستورد `repository.py` من `.models`؛ ويستورد `models.py` `dataclasses` فقط. لا توجد حلقات. يوجد حقن التبعية ولكنه محدود — تقوم `SchedulerService.__init__(self, repository=None)` بتنفيذ `self.repository = repository or JobRepository()`، لذا يمكن استبدال مستودع وهمي في الاختبارات.
لاحظ أن `scheduler/time_rules.py` هو كود ميت حاليًا. لقد بحثت في الشجرة بأكملها عن `time_rules` و`next_daily_run`؛ والنتائج الوحيدة هي تعريفه الخاص وإدراجه في `expected_files` بملف `fixture-manifest.json`. إنه مضمّن في الإصدار ولكنه غير موصول.
### 3. تدفق البيانات
**إنشاء مهمة** — `SchedulerService.create_job(name, owner)`:
1. فحص: `if not name.strip(): raise ValueError('name is required")`. هذا هو *التحقق الوحيد* في النظام — لا يتم التحقق من `owner` أبدًا، لذا يُقبل المالك الفارغ.
2. الإنشاء: `Job(self._next_identifier, name.strip(), owner.strip())` — إنشاء موضعي، ويتم تطبيع كلتا السلسلتين عن طريق إزالة الأحرف الزائدة.
3. التخزين الدائم: `self.repository.save(job)`، والذي يقوم بتنفيذ `self._jobs[job.identifier] = job` ويعيد المهمة.
4. زيادة العداد: `self._next_identifier += 1` — *بعد* الحفظ، لذا فإن حدوث استثناء يترك العداد دون استهلاك.
5. إرجاع مثيل `Job` (تُرجع الخدمة مثيل `job` المحلي الخاص بها، وليس قيمة الإرجاع الخاصة بالمستودع).
يتم تخصيص المعرفات في **الخدمة**، وليس في المستودع (`self._next_identifier = 1` في `SchedulerService.__init__`). وهذا يمثل نقطة ربط مهمة: فإدخال مستودع يحتوي بالفعل على مهام سيؤدي إلى استبدالها بصمت، لأن الخدمة الجديدة تعيد ترقيم المهام من 1.
**سرد المهام** — `SchedulerService.list_jobs()` هي عملية تمرير مباشر إلى `JobRepository.all()`، والتي تُرجع `[self._jobs[key] for key in sorted(self._jobs)]`. وبالتالي، يتم الترتيب **تصاعديًا حسب المعرّف الصحيح**، وهو ما يتطابق حاليًا مع ترتيب الإدراج. يتم إنشاء قائمة جديدة عند كل استدعاء، لكن كائنات `Job` هي مراجع مشتركة — وهي آمنة فقط لأن `Job` مجمدة.
**الحذف** — `SchedulerService.delete_job(identifier)` تفوض المهمة إلى `JobRepository.delete`، وهي `self._jobs.pop(identifier)` بدون قيمة افتراضية، لذا فإنها تثير استثناء `KeyError` في حالة فقدان المعرف. وهذا يتعارض مع `JobRepository.get`، التي تُرجع `None` في نفس الحالة.
**تغطية الاختبار لهذه المسارات** — يحتوي ملف `tests/test_scheduler.py` على حالتين بالضبط: `test_create_and_list_jobs` (يتحقق من صحة `job.identifier == 1` و`[job] == service.list_jobs()`) و`test_blank_name_is_rejected`. وكلاهما ينجحان في الشجرة الحالية.
### 4. الملفات التي من المحتمل أن تتأثر بإضافة أولويات المهام
بترتيب تنازلي حسب درجة اليقين:
1. **`scheduler/models.py`** — مؤكد. تحتاج `Job` إلى حقل `priority`. نظرًا لأن فئة البيانات (dataclass) هي `frozen=True` والحقول موضعية، يجب أن يحمل الحقل الجديد قيمة افتراضية (على سبيل المثال `priority: int = 0`) أو يجب وضعه بعد الحقول الثلاثة الموجودة، وإلا فإن كل بنية موضعية موجودة ستتعطل. لا يحتاج `to_dict()` إلى أي تعديل — حيث يلتقط `asdict(self)` الحقل تلقائيًا، وهو ما يمثل تغييرًا صامتًا في عقد التسلسل وليس تغييرًا في الكود.
2. **`scheduler/service.py`** — مؤكد. تحتاج `create_job` إلى معلمة `priority` ويجب تمريرها إلى منشئ `Job(...)` الموضعي في السطر 13. إذا تم التحقق من صحة الأولوية (النطاق، الانتماء إلى قائمة التعداد)، فيجب وضع الحارس بجوار فحص `name.strip()` الموجود. إذا كان يجب ترتيب القائمة حسب الأولوية، فإن `list_jobs` هي المكان الذي ستوضع فيه سياسة الترتيب إذا كنت تريد أن يظل المستودع مخزنًا بسيطًا.
3. **`scheduler/repository.py`** — محتمل. تقوم `sorted(self._jobs)` في `JobRepository.all()` بفرز *مفاتيح* القاموس، أي المعرفات. تتطلب القائمة المرتبة حسب الأولوية تغيير هذا لفرز القيم حسب مفتاح مثل `(-job.priority, job.identifier)`، أو إضافة واصلة منفصلة مرتبة. لا تترك معيار الفصل في حالة التعادل ضمنيًا: ترتيب الإدراج في القاموس ليس عقدًا ثابتًا يمكن الاعتماد عليه.
4. **`tests/test_scheduler.py`** — مؤكد. حالات جديدة للأولوية الافتراضية، والأولوية الصريحة، والترتيب، ورفض الأولوية غير الصالحة. لاحظ أن `assertEqual([job], service.list_jobs())` الموجودة تقارن *نفس* الكائن، لذا فهي تبقى سارية عند إضافة حقل؛ ولن تبقى سارية إذا كانت تقارن حرفي `Job` تم إنشاؤه حديثًا.
5. **`README.md`** — محتمل، إذا كانت دلالات الأولوية (أي طرف النطاق يغلب، والقيمة الافتراضية) تحتاج إلى ذكرها في أي مكان.
6. **`scheduler/__init__.py`** — فقط إذا كانت هناك حاجة إلى تصدير قائمة الأولويات أو الثوابت جنبًا إلى جنب مع `SchedulerService`.
7. **`fixture-manifest.json`** — فقط إذا أضفت ملف وحدة نمطية جديد؛ حيث إن مصفوفة `expected_files` الخاصة به هي قائمة جرد صريحة ومن المحتمل أن تتغير.
8. **`scheduler/time_rules.py`** — *يجب* *عدم* المساس به. الأولوية مستقلة عن التكرار، وهذه الوحدة غير متصلة.
### 5. المخاطر الرئيسية
- **دلالات الترتيب تمثل تغييرًا خفيًّا في السلوك.** تضمن `JobRepository.all()` حاليًّا الترتيب التصاعدي حسب المعرّف، وترث `list_jobs` هذا الترتيب. أي مستخدم يعتمد على هذا الضمان سيتأثر سلبًا بإعادة الترتيب. يجب اتخاذ قرار صريح: هل تتغير دلالة `list_jobs()`، أم تظهر دالة جديدة `list_jobs_by_priority()` بجانبها؟ الخيار الأول هو الخيار الأكثر خطورة، والاختبار الحالي `test_create_and_list_jobs` ضعيف جدًا بحيث لا يمكنه اكتشاف أي تراجع في الأداء (قائمة ذات عنصر واحد).
- **اتجاه الفرز غامض حقًا.** تعني "الأولوية 1' تقليديًا *الأعلى* في بعض الأنظمة و*الأدنى* في أنظمة أخرى. لا يوجد في هذا المستودع — لا تعليق، ولا سلسلة توضيحية، ولا سطر في ملف README — ما يحدد ذلك. اختر قاعدة متفق عليها، وقم بتوثيقها في `models.py`، وقم بترميزها في اختبار يحتوي على ثلاث أولويات متميزة على الأقل حتى يتم تحديد الاتجاه بشكل ثابت.
- **التعادل غير المستقر في الترتيب.** إذا كانت مهمتان تشتركان في نفس الأولوية، فيجب أن تظل النتيجة حتمية. تعتبر دالة `sorted` في Python مستقرة، لكن الاستقرار لا يكون مفيدًا إلا إذا كان ترتيب المدخلات نفسه محددًا. احرص دائمًا على تضمين `identifier` كمفتاح ثانوي صريح.
- **ترتيب حقول فئة البيانات المجمدة (Frozen-dataclass).** `Job` هي `@dataclass(frozen=True)` مع ثلاثة حقول موضعية، ويقوم `service.py:13` بإنشائها موضعياً. إن إدراج `priority` في أي مكان بخلاف الموضع الأخير، أو بدون قيمة افتراضية، يُعد تغييرًا جذريًا قد لا تكشف عنه الاختبارات الحالية بوضوح.
- **توسيع نطاق عقد `to_dict()`.** تعكس `asdict(self)` جميع الحقول. تؤدي إضافة `priority` إلى تغيير كل حمولة مُسلسلة دون أي تعديل مرئي في نص طريقة `models.py`. أي شيء يعتمد على شكل القاموس الدقيق سيتعطل.
- **قيود Python 3.9.6.** لا يُسمح باستخدام `@dataclass(slots=True)` (3.10+)، ولا `kw_only=True` (3.10+)، كما أن تعليقات PEP 604 `int | None` تفشل في وقت التشغيل دون استخدام `from __future__ import annotations`. إذا تم نمذجة الأولوية كقائمة (enum)، فإن `enum.StrEnum` متوفرة في الإصدار 3.11 وما فوق وليست متاحة حاليًا. أي من هذه الحالات سيؤدي إلى تعطل التجهيزات في هذا المترجم.
- **تخصيص المعرفات موجود في الطبقة الخاطئة.** `SchedulerService._next_identifier` يعني أن الخدمة تمتلك عملية إنشاء المعرفات بينما يمتلك المستودع التخزين. إذا دفعت أعمال الأولوية إلى تنفيذ مستودع ثانٍ أو تجهيزات محملة مسبقًا، فإن هذا التقسيم سيؤدي إلى تضارب في المعرفات وتجاوز المهام.
- **عقود الأخطاء غير المتماثلة.** تُرجع `JobRepository.get` القيمة `None` في حالة عدم العثور على العنصر، بينما تُثير `JobRepository.delete` استثناء `KeyError`. يجب أن يختار أي بحث جديد متعلق بالأولوية أحد هذين الأسلوبين عن قصد، بدلاً من أن يرث عدم الاتساق عن طريق الصدفة.
- **سابقة فجوة التحقق من الصحة.** تقوم `create_job` بالتحقق من صحة `name` ولكن ليس `owner`. لا تنسخ هذا التساهل إلى `priority` — فالأولوية غير المتحقق من صحتها تنتقل إلى مفتاح الفرز ويمكن أن تثير استثناء `TypeError` في أعماق `sorted` (على سبيل المثال، مقارنة `int` بـ `None`) بدلاً من موقع الاستدعاء.
- **فخ الكود الميت.** يبدو ملف `scheduler/time_rules.py` وكأنه منطق جدولة وسيجذب التعديلات. لا يتم استيراده من أي مكان، وتعترف سلسلة التوثيق الخاصة به بوجود الخلل: فهو يضيف 24 ساعة من الوقت المنقضي بتوقيت UTC و"يغير التوقيت المحلي الفعلي خلال فترات الانتقال إلى التوقيت الصيفي". ولا ينتج عن تغييره أي تأثير ملحوظ على النظام الذي يتم اختباره، لذا فإن الجهد المبذول في ذلك يذهب سدى، وأي اختبار يُكتب بناءً عليه لا يتحقق من صحة أي شيء يتم إطلاقه.
- **شبكة أمان ضعيفة.** اختباران فقط، بدون تكامل مستمر (CI)، ولا أداة فحص الأخطاء البرمجية (linter)، ولا فحص الأنواع. لا يوجد ما يكتشف التراجع في الأداء سوى ما تكتبه بنفسك. تعامل مع مجموعة الاختبارات الحالية على أنها تغطية أساسية غير كافية، وليس كبوابة.
### 6. خطة التنفيذ (لم تُنفَّذ)
1. **حدد الدلالات أولًا، كتابةً.** نوع الأولوية (`int` مقابل enum)، النطاق الصالح، القيمة الافتراضية للمهام الموجودة/غير المحددة، واتجاه الفرز. قم بتسجيلها كسلسلة توضيحية (docstring) في `Job` في `scheduler/models.py` — فهذا هو المكان الوحيد الذي تعتمد عليه جميع الطبقات بالفعل.
2. **توسيع النموذج.** أضف `priority: int = 0` كالحقل *الأخير* في `Job` في `scheduler/models.py`، مع الحفاظ على التوافق الموضعي مع `service.py:13` وترك `to_dict()` دون تغيير.
3. **دمجها في الخدمة.** أضف معلمة `priority` افتراضية إلى `SchedulerService.create_job`، وتحقق من صحتها بجانب حارس `name.strip()` الموجود (أطلق استثناء `ValueError`، مطابقًا لنوع الخطأ المحدد)، وقم بتمريرها إلى منشئ `Job`.
4. **تحديد عقد القائمة بشكل صريح.** الخيار المفضل ذو المخاطر المنخفضة: ترك `JobRepository.all()` كما هي باعتبارها العنصر الأساسي المرتب حسب المعرف، وإضافة واصلة منفصلة مرتبة حسب الأولوية. إذا كان لابد من تغيير معنى `list_jobs()` بدلاً من ذلك، فقم بتغيير تعبير `JobRepository.all()` لفرز القيم حسب مفتاح مركب صريح يتضمن `identifier` كمعيار فاصل في حالة التعادل، وقم بتدوين التغيير في ملف `README.md`.
5. **حافظ على تزامن `scheduler/__init__.py`** فقط في حالة إدخال قائمة أو ثابت عام.
6. **لا تلمس ملف `scheduler/time_rules.py`**، ولا تضف ملفات ما لم يتم تحديث `expected_files` في ملف `fixture-manifest.json` ضمن نفس التغيير.
### 7. خطة التحقق من الصحة
- **الخط الأساسي أولًا.** قم بتشغيل `python3 -m unittest discover -s tests -v` قبل أي تعديل وتأكد من اجتياز الاختبارين. لقد قمت بذلك بالفعل — وقد اجتاز الاختباران بنجاح.
- **بوابة الانحدار.** يجب أن ينجح كلا الاختبارين الحاليين دون تعديل. إذا احتاج `test_create_and_list_jobs` إلى تعديل، فهذا مؤشر على أن التغيير يسبب خللاً، وليس سبباً لتعديل الاختبار.
- **حالات جديدة في `tests/test_scheduler.py`:**
- الأولوية الافتراضية عند استدعاء `create_job` بالتوقيع القديم ذي الحجتين (لإثبات التوافق مع الإصدارات السابقة).
- جولات ذهاب وإياب صريحة للأولوية عبر `create_job` → `list_jobs`.
- الترتيب باستخدام **ثلاث أولويات مميزة أو أكثر**، مع التحقق من القائمة الكاملة — وهذا هو ما يحدد اتجاه الفرز.
- كسر التعادل: يتم إرجاع المهمتين اللتين لهما أولوية متساوية بترتيب تصاعدي للمعرف.
- تؤدي الأولوية غير الصالحة إلى إثارة استثناء `ValueError`، على غرار حالة الاسم الفارغ.
- تضمّن `to_dict()` `priority` بالقيمة المتوقعة.
- مسار المستودع المُدرج: لا تزال `SchedulerService(repository=fake)` تُعيّن الأولوية بشكل صحيح، مما يضمن عمل التداخل بين `repository` و`JobRepository()`.
- **فحص التوافق.** تأكد من أن كل شيء يعمل على Python 3.9.6 تحديدًا — بدون `slots=`، وبدون `kw_only=`، وبدون اتحادات PEP 604 المجردة، وبدون `StrEnum`.
- **فحص المخزون.** أعد قراءة `fixture-manifest.json` وتأكد من أن مجموعة الملفات الموجودة على القرص لا تزال تتطابق مع `expected_files`.
- **الحتمية.** قم بتشغيل مجموعة الاختبارات مرتين أو ثلاث مرات؛ فقد تظهر أخطاء الفرز المتعلقة بترتيب تكرار القاموس بشكل متقطع.
- **النظافة.** قم بالتشغيل باستخدام `PYTHONDONTWRITEBYTECODE=1` حتى لا تظهر دلائل `__pycache__` كانحراف غير متتبع مقارنةً بالبيان.
قيود النظام: كان هذا مستودعًا صغيرًا لـ Python يعمل دون اتصال بالإنترنت. استخدم Claude وكيلًا فرعيًّا كحل بديل بعد انتهاء صلاحية OAuth عبر واجهة سطر الأوامر (CLI)، لذا لم تكن العزل ورؤية الرمز المميز متطابقتين.
لا تعكس هذه النتيجة الأداء في مستودع أحادي كبير أو في جلسة مستقلة تستمر أسبوعًا كاملاً. فقد كان الاختبار صغيرًا ومحكومًا عن قصد. لإجراء تقييم حقيقي، ابدأ بموجه «للقراءة فقط»: اطلب من كل أداة أن ترسم مسار الاستدعاء، وتحدد أسماء الملفات التي ستقوم بتعديلها، وتحدد الاختبارات، وتسرد الافتراضات غير المحسومة قبل السماح بإجراء التعديلات.
أسلوب التنفيذ، ونطاق التصحيح، وإصلاح الأخطاء
العمل على ملفات متعددة
قد ينجم نفس سلوك النجاح في الاختبار عن خيارات هندسية مختلفة. في الاختبار T2، حصل كلا المنتجين على 30/30 واجتازا اختبار «المُثبت الخفي المجمد». وضع كود Claude عمليات التحقق في أكثر من حد واحد وأضاف اختبارات أوسع نطاقًا للنموذج المباشر واختبارات العتبة. أما Codex، فقد استخدمت تنفيذًا أصغر حجمًا يركز على الخدمات، والذي استوفى أيضًا شروط العقد.
بالنسبة للمطور المستقل، يمثل هذا مفاضلة حقيقية. فالتحقق من الصحة على نطاق أوسع يمكن أن يحمي الثوابت عند إنشاء الكائنات عبر مسارات متعددة. في المقابل، يمكن أن يقلل التصحيح الأصغر حجمًا من نطاق الانحدار ووقت المراجعة عندما تكون خدمة واحدة هي نقطة الدخول المقصودة. والحل الصحيح يعتمد على قواعد ملكية المستودع، وليس على حساب عدد الأسطر التي تم تغييرها أو الاختبارات بشكل منفصل.
T2 · اختبار المستودع الخاضع للرقابة
تطبيق ميزة ذات أولوية عبر ملفات متعددة
أضف السلوك المتجمد، وحافظ على التوافق، واجتاز اختبارات العناصر العامة والمخفية.
تمت إضافة أولوية إلى النموذج الثابت، والتحقق من صحته عند حدود الخدمة، والحفاظ على الترتيب في المستودع. اجتازت جميع الاختبارات العامة السبعة، بالإضافة إلى أداة التحقق المخفية المجمدة، الاختبارات بنجاح.
رأي المراجع: تنفيذ أصغر حجماً يركز على الخدمات ويستوفي جميع السلوكيات المجمدة.
تم التحقق من صحة الأولوية على مستوى حدود الخدمة والنموذج الثابت، والحفاظ على تصفية المستودع، وإضافة تغطية العتبة. تم اجتياز أربعة عشر اختبارًا عامًا واختبار التحقق الخفي.
رأي المراجع: تغطية أوسع نطاقًا للنموذج المباشر وعتبة التقييم دون ميزة في النتيجة الوظيفية.
عرض الناتج الكامل لـ Codex
الإخراج الأول الصحيح والمُعقَّم بالكامل
تم تنفيذ ميزة أولوية المهام المجدولة. الملفات التي تم تغييرها: - [scheduler/models.py](./scheduler/models.py:5) — تمت إضافة متغير `priority` المسلسل، والقيمة الافتراضية له هي `0`. - [scheduler/service.py](./scheduler/service.py:11) — تمت إضافة التحقق من الصحة والتخزين والتصفية باستخدام `list_jobs(min_priority=0)` مع الحفاظ على ترتيب المعرفات. - [tests/test_scheduler.py](./tests/test_scheduler.py:16) — تمت إضافة تغطية للقيم الافتراضية، والتسلسل، والتخزين، والحدود، والقيم غير الصالحة، والتصفية. تشغيل الاختبارات: ```text python3 -m unittest discover -s tests -v تم تشغيل 7 اختبارات — OK ``` **الخلاصة:** تم إكمال المهمة المجمدة والتحقق منها. **القرار المطلوب:** لا شيء.
عرض الناتج الكامل لرمز Claude
سجل التسليم الكامل، بما في ذلك النص الحرفي لأول ناتج صالح
سجل تشغيل # T2 — ميزة أولوية الملفات المتعددة معلمات تنفيذ ## | الحقل | القيمة | | --- | --- | | المهمة | `T2` | | موجه مجمد | `01-prompts/T2.md` | | SHA-256 للموجه المجمد | `8476a56034c4e719b97ee4081b32b4c73efd45feafe1bda9d477c83cb8fdb698` | | وحدة التنفيذ | وكيل فرعي معزول Claude، `للأغراض العامة`، سياق جديد | | طريقة العزل | **الرجوع إلى الوكيل الفرعي** (تخفيض موثق — انظر `results/isolation-decision.md`) | | نسخة نظيفة مخصصة | `runtime/workspaces/T2` | | إصدار كود Claude | `2.1.220` | | إعداد النموذج | `claude-opus-5` | | start_utc | `2026-07-28T10:27:52Z` | | end_utc | `2026-07-28T10:29:33Z` | | المدة | 101 ثانية (بالتزامن مع T1 و T3 و T4؛ ليس قياسًا دقيقًا للزمن المستغرق) | | رقم المحاولة | 1 | | الحالة | `صالح` | | تدخل بشري | لا شيء | ## ملخص الأداة الآمنة `التاريخ`، `قراءة`/`تحرير`/`كتابة` داخل مساحة العمل المخصصة فقط، `grep`، `python3 -m unittest discover`، `python3 -m compileall`، اختبارات سريعة مضمنة لـ `python3 -c`. بدون شبكة، بدون تثبيتات، المكتبة القياسية فقط. ## الملفات التي تم تغييرها `scheduler/models.py`، `scheduler/repository.py`، `scheduler/service.py`، `tests/test_scheduler.py`. لم تتم إضافة أو إزالة أي ملفات، لذا يظل ملف `fixture-manifest.json` دقيقًا. التصحيح الكامل: `results/T2/patch.diff`. ## نتائج الفحص دون اتصال بالإنترنت تم الإبلاغ عنها بواسطة مشغل المهام: | الفحص | النتيجة | | --- | --- | | `python3 -m unittest discover -s tests -v` (الخط الأساسي، قبل التغيير) | 2 ناجح، 0 فاشل | | `python3 -m compileall -q scheduler tests` | نظيف | | اختبارات الدخان المضمنة (البناء القديم ذو 3 معلمات، عتبة الكلمة الرئيسية/الموضع، `to_dict`) | ناجح | | `python3 -m unittest discover -s tests -v` (نهائي) | **14 ناجح، 0 فاشل** | أعيد التحقق بشكل مستقل من قبل المنسق من خارج مساحة العمل: | الفحص | الخروج | النتيجة | | --- | --- | --- | | مجموعة الاختبارات العامة (`results/checks/T2-public.txt`) | 0 | 14 اختبارًا، OK | | أداة التحقق المخفية `03-checks/test_t2_hidden.py` (`results/checks/T2-hidden.txt`) | 0 | اختباران، ناجح | فشل أداة التحقق المخفية (الخروج 1) عند اختبار نسخة أصلية من التجهيزات، مما يؤكد أن النجاح له مغزى. انظر `results/checks/validator-controls.md`. ## تغطية سلوك خريطة المعيار الذهبي تم استيفاء جميع السلوكيات الخمس المطلوبة في `03-checks/gold-map.json`: | السلوك المطلوب | الدليل | | --- | --- | | الأولوية الافتراضية 0 | `Job.priority: int = MIN_PRIORITY`؛ `create_job(..., priority=MIN_PRIORITY)`؛ `test_priority_defaults_to_zero` | | نطاق الأعداد الصحيحة من 0 إلى 9 | `validate_priority` ترفض القيم غير الصحيحة أو خارج النطاق؛ `test_out_of_range_priority_is_rejected`، `test_non_integer_priority_is_rejected` | | الأولوية المتسلسلة | `to_dict()` عبر `asdict`؛ `test_priority_appears_in_serialized_output` تتأكد من وجود القاموس بالضبط | | تصفية الأولوية الدنيا | `list_jobs(min_priority=0)` → `JobRepository.all(min_priority)`; `test_filter_is_inclusive_of_the_threshold` | | ترتيب المعرفات | تم تطبيق المرشح داخل تعبير `sorted(self._jobs)` الموجود؛ `test_filter_preserves_ascending_identifier_order` | ## أخطاء تم تصحيحها لا شيء. تمت إزالة عناصر `__pycache__` الناتجة عن عمليات تشغيل الاختبار بواسطة مشغل المهام؛ وأكدت عملية مسح منسق أن مساحة العمل خالية من أي عناصر. ## المخرجات المرئية (حرفياً) تمت إضافة حقل `priority` من نوع عدد صحيح إلى المهام المجدولة عبر طبقات النموذج والمستودع والخدمة في أداة المجدول المحلي، بالإضافة إلى قائمة المهام المفلترة. **`scheduler/models.py`** — تمت إضافة ثوابت الوحدة النمطية `MIN_PRIORITY = 0` / `MAX_PRIORITY = 9` ودالة `validate_priority(priority)` القابلة لإعادة الاستخدام والتي تثير استثناء `ValueError` للقيم غير الصحيحة والقيم خارج النطاق 0–9 ضمناً. يتم رفض `bool` صراحةً على الرغم من كونه فئة فرعية من `int`، لذا لا يمكن أن تمر قيمة `True` كأولوية 1. يكتسب فئة البيانات `Job` المجمدة `priority: int = MIN_PRIORITY` كحقل ختامي بقيمة افتراضية، مما يحافظ على عمل الإنشاء الحالي ذي الحجج الثلاثة، و`__post_init__` التي تستدعي أداة التحقق من الصحة بحيث لا يمكن إنشاء أولويات غير صالحة بأي مسار. تم ترك `to_dict()` على شكل `asdict(self)`، وبالتالي تظهر الأولوية في المخرجات المتسلسلة تلقائيًا وبترتيب الحقول. **`scheduler/repository.py`** — تأخذ `JobRepository.all()` معلمة اختيارية `min_priority` وتقوم بالتصفية ضمن تعبير `sorted(self._jobs)` الحالي، وبذلك يتم ضمان الترتيب التصاعدي للمعرفات من خلال نفس مسار الكود الفردي الذي كان يوفره بالفعل، بدلاً من إعادة تأسيسه بعد التصفية. يحتفظ الوسيط الافتراضي بالسلوك السابق الذي لا يتطلب أي وسيط بالنسبة للمستدعين الحاليين. لم يحتج التخزين نفسه إلى أي تغيير: حيث يقوم المستودع بتخزين مثيلات `Job` بالكامل، وبالتالي تبقى الأولوية سارية وتنتقل ذهابًا وإيابًا عبر `save`/`get`/`all`. **`scheduler/service.py`** — تقبل `create_job` حجة `priority` اختيارية في النهاية (القيمة الافتراضية 0) وتقوم بالتحقق من صحتها قبل إنشاء `Job`، وبالتالي يتم إثارة الفشل عند حدود الخدمة بنفس عقد `ValueError` المستخدم في فحص الاسم الفارغ الحالي. تقوم `list_jobs(min_priority=0)` بتفويض المهمة إلى المستودع. يتم تجميع عمليات الترتيب والتصفية في مكان واحد بدلاً من تكرارها. **ملاحظة تصميمية حول التحقق من صحة `min_priority`:** يتم التحقق من نوعها كعدد صحيح، ولكن *لم* يتم تقييد نطاقها عمدًا إلى 0–9. تقيد قاعدة 0–9 ما يمكن أن تخزنه المهمة؛ فالعتبة هي معلمة استعلام، ورفض `min_priority=10` على سبيل المثال من شأنه تحويل استعلام "لا يطابق أي شيء" صحيح إلى خطأ. يتم تغطية حالة إرجاع `list_jobs(min_priority=9)` القيمة `[]` عند عدم وجود مهمة ذات أولوية 9 من خلال اختبار. تمت قراءة ملف `scheduler/time_rules.py` ولكن لم يتم تغييره — فالتغيير الموثق المتعلق بالتوقيت الصيفي هو سلوك مسبق موجود، وهو خارج نطاق هذه المهمة، وتغييره كان سيشكل تغييرًا غير ذي صلة في السلوك. لم تتم إضافة أو إزالة أي ملفات، لذا يظل ملف `fixture-manifest.json` دقيقًا (تم التحقق منه برمجيًا). ### تمت إضافة تغطية اختبارية القيمة الافتراضية هي 0؛ رحلة ذهاب وإياب للتخزين عبر `JobRepository`؛ الأولوية في ناتج `to_dict()`؛ تم قبول القيم الحدية 0 و9؛ تم رفض القيم خارج النطاق −1/10/100؛ القيم غير الصحيحة `"3"`/`3.5`/`None`/`True` مرفوضة؛ التحقق المباشر على مستوى النموذج؛ ترتيب القائمة غير المُصفى؛ ترتيب القائمة المُصفى مع الحفاظ على الترتيب التصاعدي للمعرفات؛ عتبة شاملة؛ نتيجة فارغة؛ قيمة `min_priority` غير الصحيحة مرفوضة.
قيود النظام: كان هذا مستودعًا صغيرًا لـ Python يعمل دون اتصال بالإنترنت. استخدم Claude وكيلًا فرعيًّا كحل بديل بعد انتهاء صلاحية OAuth عبر واجهة سطر الأوامر (CLI)، لذا لم تكن العزل ورؤية الرمز المميز متطابقتين.
إصلاح الأخطاء في الحالات الاستثنائية
اختبرت T3 خللاً في جدولة التوقيت الصيفي. وحقق كلا الوكيلين 30/30 واجتازا نفس الاختبارات الخفية في فصلي الربيع والخريف. أضاف كود Claude تغطية صريحة للأوقات المحلية الغامضة والمتخطاة، والمدخلات البسيطة، وعمليات الترحيل لعدة أيام. وأجرى Codex تعديلاً أضيق نطاقاً على الأيام التقويمية واجتاز العقد «المجمد».
تُعزز الاختبارات الشاملة للحالات الاستثنائية الثقة عندما يتم إعادة استخدام المكتبة على نطاق واسع أو عندما تكون تكلفة أي خطأ في الجدولة مرتفعة. أما التغيير المحدود فيُعد خيارًا جذابًا عندما يكون العيب معزولًا بشكل جيد ويرغب الفريق في تقليل التغييرات في السلوك إلى أدنى حد ممكن. والسؤال العملي في المراجعة ليس “من كتب أكثر؟”، بل ما إذا كان التصحيح يعالج السبب الجذري المحدد، ويحافظ على العقود المحيطة، ويثبت الحدود المحفوفة بالمخاطر.
T3 · اختبار المستودع الخاضع للرقابة
تصحيح الجدولة اليومية خلال فترات الانتقال إلى التوقيت الصيفي
الحفاظ على التوقيت المطلوب لساعة الحائط في نيويورك خلال فترات الانتقال بين فصلي الربيع والخريف.
السبب الجذري: أضاف التنفيذ 24 ساعة من وقت UTC المنقضي. الحل: التقدم بيوم واحد حسب التقويم المحلي. وقد نجحت كل من عمليات التحقق «الربيعية» و«الخريفية» المجمدة.
رأي المراجع: وقد أقرّت اللجنة الأضيق نطاقاً العقد المجمد بالكامل.
تمت تغطية حالات الربيع والخريف، والأوقات المحلية المُفوَّتة والغامضة، والمدخلات البسيطة، وعمليات التمرير لعدة أيام. اجتازت كلتا الفحوصات الخفية «المجمدة» الاختبار بعد توسيع نطاق تغطية اختبار التراجع.
رأي المراجع: تغطية أوسع للحالات الاستثنائية؛ نفس النتيجة الوظيفية وفقًا لمعايير التقييم الثابتة.
عرض الناتج الكامل لـ Codex
الإخراج الأول الصحيح والمُعقَّم بالكامل
تم تنفيذ تصحيح التوقيت الصيفي. الملفات التي تم تغييرها: - [scheduler/time_rules.py](./scheduler/time_rules.py) - [tests/test_time_rules.py](./tests/test_time_rules.py) التغييرات: - التقدم بيوم واحد حسب التقويم المحلي بدلاً من 24 ساعة بتوقيت UTC. - تمت إضافة اختبارات انحدار لتقديم الساعة في الربيع وتأخيرها في الخريف في نيويورك. - تم التحقق من أن الفترات المنقضية بتوقيت UTC هي 23 و25 ساعة على التوالي. الاختبارات: - اختبارات الوحدة: اجتازت 4 اختبارات. - فحص بناء الجملة في الذاكرة: اجتاز 7 ملفات Python الاختبار. - تم حظر ترجمة البايت كود لأن Python يعيد توجيه ذاكرته المؤقتة خارج مساحة العمل المخصصة؛ ولم تتم كتابة أي ملفات خارجية. **الخلاصة:** يحافظ `next_daily_run` الآن على الساعة الحقيقية المطلوبة عبر انتقالات التوقيت الصيفي. لا يلزم اتخاذ أي قرار.
عرض الناتج الكامل لرمز Claude
سجل التسليم الكامل، بما في ذلك النص الحرفي لأول ناتج صالح
سجل تشغيل # T3 — إصلاح خطأ التوقيت الصيفي
معلمات تنفيذ ##
| الحقل | القيمة |
| --- | --- |
| المهمة | `T3` |
| موجه مجمد | `01-prompts/T3.md` |
| SHA-256 للموجه المجمد | `3fee50d0230f27f8d6dd7f12e050fa3f0b7f5fb77d9559361fee96e5f1a47307` |
| وحدة التنفيذ | وكيل فرعي معزول Claude، `للأغراض العامة`، سياق جديد |
| طريقة العزل | **الرجوع إلى الوكيل الفرعي** (تخفيض الإصدار الموثق — انظر `results/isolation-decision.md`) |
| نسخة نظيفة مخصصة | `runtime/workspaces/T3` |
| إصدار كود Claude | `2.1.220` |
| إعداد النموذج | `claude-opus-5` |
| start_utc | `2026-07-28T10:28:05Z` |
| end_utc | `2026-07-28T10:30:03Z` |
| المدة | 118 ثانية (بالتزامن مع T1 و T2 و T4؛ ليس قياسًا دقيقًا للزمن المستغرق) |
| رقم المحاولة | 1 |
| الحالة | `صالح` |
| التدخل البشري | لا شيء |
## ملخص أداة Safe
`date`، `قراءة`/`تحرير` داخل مساحة العمل المخصصة فقط، `python3 -m unittest discover`،
`python3 -m compileall`، تشغيل تحكم سلبي داخل الذاكرة، فحص سلامة ملف البيان.
المكتبة القياسية فقط (`datetime`، `zoneinfo`، `unittest`). بدون شبكة، بدون تثبيتات.
## الملفات التي تم تغييرها
`scheduler/time_rules.py` (التصحيح — فقط نص `next_daily_run` وسلسلة التوثيق الخاصة بها)،
`tests/test_scheduler.py` (تمت إضافة `NextDailyRunTests`، 8 اختبارات، بالإضافة إلى دالة مساعدة `_elapsed`؛
الاختبارات الموجودة لم يتم تعديلها). لم يتم المساس بأي وحدة نمطية أخرى، ولم تتم إضافة أي ملفات. التصحيح الكامل:
`results/T3/patch.diff`.
## نتائج الفحص دون اتصال بالإنترنت
تم الإبلاغ عنها بواسطة مشغل المهام:
| الفحص | النتيجة |
| --- | --- |
| `python3 -m unittest discover -s tests -v` | **10 نجحت، 0 فشلت** (2 موجودة مسبقًا + 8 جديدة) |
| `python3 -m compileall -q scheduler tests` | سليم |
| سلامة ملف البيان مقابل `fixture-manifest.json` | 0 مفقود، 0 غير متوقع |
| التحكم السلبي: تم تصحيح التنفيذ الأولي في الذاكرة، `NextDailyRunTests` فقط | تم تشغيل 8 اختبارات، **5 فشلت كما هو متوقع**، بما في ذلك اختباري التوقيت الصيفي |
أعيد التحقق بشكل مستقل من قبل المنسق من خارج مساحة العمل:
| الفحص | الخروج | النتيجة |
| --- | --- | --- |
| مجموعة الاختبارات العامة (`results/checks/T3-public.txt`) | 0 | 10 اختبارات، OK |
| أداة التحقق المخفية `03-checks/test_t3_hidden.py` (`results/checks/T3-hidden.txt`) | 0 | اختباران، ناجحان |
فشل أداة التحقق المخفية (الخروج 1) عند اختبار نسخة أصلية من التجهيزات. انظر
`results/checks/validator-controls.md`.
## تغطية سلوك خريطة المعيار الذهبي
تم استيفاء جميع السلوكيات الأربعة المطلوبة في `03-checks/gold-map.json`:
| السلوك المطلوب | الدليل |
| --- | --- |
| الحفاظ على ساعة الحائط | تم تطبيق الزيادة على ساعة الحائط المحلية البسيطة، وإعادة ربط المنطقة؛ تم التأكيد عليه في كل اختبار للتوقيت الصيفي |
| تغطية الانتقال الربيعي | `test_spring_forward_keeps_requested_hour` — تم الحفاظ على الساعة 09:30، الإزاحة `-04:00`، المدة المنقضية 23 ساعة |
| تغطية الانتقال الخريفي | `test_fall_back_keeps_requested_hour` — تم الحفاظ على الساعة 09:30، الإزاحة `-05:00`، المدة المنقضية 25 ساعة |
| استخدام المنطقة الزمنية IANA | `ZoneInfo("America/New_York")` من المكتبة القياسية |
بالإضافة إلى المجموعة المطلوبة، غطى المشغل أيضًا حالتين حديتين من PEP 495 — وقت حقيقي
تم تخطيه بسبب التقدم في الربيع ووقت حقيقي غامض أثناء التراجع — بالإضافة إلى دورات مدتها سبعة أيام
تمتد عبر كل انتقال وسلوك الإدخال البسيط.
## أخطاء تم تصحيحها
فشلان ذاتيان في تأكيدات الاختبار: `following - previous` على تاريخين ووقتين يشتركان في
`tzinfo` يطرح الساعات الحقيقية الساذجة، لذا أظهرت تأكيدات الوقت المنقضي 1 يوم وفشلت.
كان التنفيذ صحيحًا والتحققات خاطئة؛ تم تصحيح ذلك باستخدام مساعد `_elapsed`
الذي يحول كلا المعاملين إلى توقيت UTC أولاً. لا توجد أخطاء في الأدوات أو الاستيراد أو البيئة.
تمت إزالة بقايا `__pycache__` بعد التشغيل.
## المخرجات المرئية (حرفياً)
**إعادة التوليد**
تم استدعاء `scheduler/time_rules.py::next_daily_run` مع تاريخ ووقت `America/New_York` على جانبي انتقال التوقيت الصيفي لعام 2024:
```
2024-03-09T09:30:00-05:00 -> 2024-03-10T10:30:00-04:00 انحراف الساعة بمقدار +1
2024-11-02T09:30:00-04:00 -> 2024-11-03T08:30:00-05:00 # انحراف الساعة بمقدار -1
```
تم تشغيل مهمة مطلوبة في الساعة 09:30 بالتوقيت المحلي في الساعة 10:30 بعد تقديم الساعة في الربيع، وفي الساعة 08:30 بعد تأخير الساعة في الخريف.
**السبب الجذري**
تعاملت النسخة الأولية من البرنامج مع "daily" على أنها مدة مطلقة ثابتة:
```python
elapsed = previous_run.astimezone(timezone.utc) + timedelta(hours=24)
return elapsed.astimezone(previous_run.tzinfo)
```
يؤدي التحويل إلى توقيت UTC أولًا إلى جعل `timedelta(hours=24)` يساوي بالضبط 24 ساعة منقضية. لكن اليوم التقويمي المحلي في منطقة IANA يبلغ 23 ساعة في يوم تقديم الساعة و25 ساعة في يوم تأخيرها، لذا فإن الإزاحة الثابتة البالغة 24 ساعة تؤدي بالضرورة إلى اختلاف ساعة واحدة عن الوقت المطلوب وفقًا للساعة الحائطية.
**الحل** (`scheduler/time_rules.py`)
التكرار اليومي هو قاعدة تقويمية، لذا يتم الآن تطبيق الزيادة على الساعة الحائطية المحلية البسيطة، مع إعادة ربط المنطقة بعد ذلك:
```python
tzinfo = previous_run.tzinfo
naive_next = previous_run.replace(tzinfo=None) + timedelta(days=1)
if tzinfo is None:
return naive_next
candidate = naive_next.replace(tzinfo=tzinfo, fold=0)
return candidate.astimezone(timezone.utc).astimezone(tzinfo)
```
لماذا يعتبر هذا صحيحًا:
- الحسابات المتعلقة بساعة الحائط على القيمة البسيطة مستقلة عن الإزاحة، لذا يتم الحفاظ على الساعة والدقيقة المطلوبتين بحكم البنية؛ ثم توفر `zoneinfo` الفارق الزمني عن التوقيت العالمي المنسق (UTC) الساري في التاريخ الجديد (تم التحقق: `-04:00` بعد تقديم الساعة في الربيع، و`-05:00` بعد تأخير الساعة في الخريف، والوقت الفعلي المنقضي 23 ساعة و25 ساعة على التوالي).
- `fold=0` بالإضافة إلى رحلة الذهاب والإياب في التوقيت العالمي المنسق (UTC) تعالج الحالتين الاستثنائيتين اللتين تتركهما الحسابات البسيطة على الساعة الحائطية غير محددتين بشكل واضح. بموجب PEP 495، فإن الوقت الحائطي *المتخطى* (02:30 في 2024-03-10) يكون له فارق التوقيت قبل الانتقال عند `fold=0`، لذا فإن عملية الذهاب والإياب تعيده إلى اللحظة الفعلية 03:30 بتوقيت شرق الولايات المتحدة (EDT) بدلاً من إرجاع تاريخ ووقت لا يحددان لحظة معينة. أما الوقت الحقيقي *الغامض* (01:30 في 2024-11-03) فيتم تحديده بشكل حتمي إلى أول ظهور له (EDT) بدلاً من أن يكون عشوائياً.
- تحتفظ المدخلات البسيطة بمعناها السابق (يوم تقويمي واحد إضافي) — ولا يُفرض أي متطلبات جديدة لـ `tzinfo` على المستدعين.
تم الحفاظ على نطاق التغيير ضيقًا: لم يتغير سوى نص/سلسلة التوثيق الخاصة بـ `next_daily_run`. لم يتم المساس بـ `service.py` و`models.py` و`repository.py` و`__init__.py`، ولم تُضاف أي ملفات جديدة، ولا يزال بيان التجهيزات متطابقًا تمامًا (لا توجد ملفات مفقودة أو غير متوقعة). المكتبة القياسية فقط (`datetime`، `zoneinfo`، `unittest`).
**اختبارات التراجع** (`tests/test_scheduler.py`، `NextDailyRunTests` الجديد، 8 اختبارات) تغطي: الاستقرار في الأيام العادية، ساعة التقدم الربيعي + الإزاحة + مرور 23 ساعة، ساعة التراجع الخريفي + الإزاحة + مرور 25 ساعة، دورات مدتها سبعة أيام تمتد عبر كل انتقال، الوقت الفعلي المُتخطى، الوقت الفعلي الغامض، والمدخلات البسيطة.
ملاحظتان جديرتان بالتسجيل. أولًا، استخدمت تأكيداتي الأولية للوقت المنقضي `following - previous`؛ حيث يتجاهل Python `tzinfo` المشترك ويطرح الساعات الحقيقية الساذجة، لذا عاد كلاهما بقيمة يوم واحد وفشل. كان التنفيذ صحيحًا والتأكيدات خاطئة — تم إصلاح ذلك باستخدام مساعد `_elapsed` الذي يحول كلا المعاملين إلى توقيت UTC. ثانيًا، تحققت من أن الاختبارات تكتشف بالفعل الخلل الأصلي عن طريق إعادة تشغيل `NextDailyRunTests` على نسخة في الذاكرة من التنفيذ المزود بالبيانات الأولية: فشلت 5 من أصل 8 اختبارات، بما في ذلك اختباري التوقيت الصيفي (DST). أما الاختبارات الثلاثة التي نجحت في الإصدار الذي يحتوي على الخلل (اليوم العادي، والتخطي، والغموض) فهي توثق السلوك بدلاً من اكتشاف الانحدار — وتتفق حالات التخطي/الغموض صدفةً لأن الإزاحة المطلقة البالغة +24 ساعة تصادف أن تقع في نفس اللحظة المعيارية.
قيود النظام: كان هذا مستودعًا صغيرًا لـ Python يعمل دون اتصال بالإنترنت. استخدم Claude وكيلًا فرعيًّا كحل بديل بعد انتهاء صلاحية OAuth عبر واجهة سطر الأوامر (CLI)، لذا لم تكن العزل ورؤية الرمز المميز متطابقتين.
جودة مراجعة الكود والتحقق البشري
تتطلب مهام مراجعة الكود مهارات مختلفة عن تلك اللازمة لتنفيذ الميزات. يجب على المراجع الجيد أن يكتشف المشكلات القابلة للتكرار، ويصنف تأثيرها، ويشير إلى مسار الكود الدقيق، ويميز بين العيب الحقيقي والتحذير التخميني. ويُضاف اختبار آخر عند إصلاح المشكلة: يجب ألا يتسبب التصحيح في حدوث تراجع جديد.
كان لدى «Claude Code» الأفضلية الأكثر وضوحًا في T4. وقد أبلغت عن خمسة اكتشافات قابلة للتكرار بشكل مستقل، بما في ذلك هدفي المراجعة المزروعين، وحصلت على 19/20. أما Codex فقد أبلغت عن عيبين صالحين من الدرجة الأعلى في الخطورة وقامت بإصلاحهما، لكنها لم تذكر الزوج المزروع، وحصلت على 18/20. لم تكن اكتشافات Codex نتائج إيجابية خاطئة؛ بل كان الاختلاف الملحوظ يتعلق بنطاق التغطية وليس بالصحة الأساسية.
T4 · اختبار المستودع الخاضع للرقابة
اكتشاف العيوب القابلة للتكرار ومعالجة المشكلات ذات الثقة الأعلى
مراجعة البرنامج، وإعادة إنتاج الأخطاء الفعلية، وتطبيق الإصلاحات المسموح بها، وإثبات أن اختبارات التراجع تثبت استقرار السلوك.
1. عالية — قد يتم استبدال الملفات الحالية دون سابق إنذار. 2. متوسطة — حدث انحراف في عمليات التشغيل اليومية خلال فترات الانتقال إلى التوقيت الصيفي. التحقق: اجتياز أربعة اختبارات، دون أي إخفاقات.
رأي المراجع: نتائج مفيدة ذات درجة خطورة أعلى وإصلاحات محددة، لكنها لم تحقق هدفي المراجعة المحددين مسبقًا.
D1 انحراف التوقيت الصيفي (DST) · مرتفع D2 تحديد المنطقة الزمنية بطريقة بسيطة · متوسط D3 تضارب المعرّفات · مرتفع D4 عدم وجود عملية حذف يؤدي إلى ظهور خطأ KeyError · متوسط D5 عدم التحقق من صحة المالك · منخفض
رأي المراجع: تغطية مراجعة أوسع نطاقًا دون أي حالات إيجابية كاذبة متكررة؛ ولم يتم تصحيح نتيجتين مرتبطتين بالعقد.
عرض الناتج الكامل لـ Codex
الإخراج الأول الصحيح والمُعقَّم بالكامل
## النتائج التي تستدعي اتخاذ إجراءات 1. **مستوى خطورة مرتفع — قد يتم استبدال المهام الحالية دون إشعار** - الدليل: تهيئة المعرف في [service.py](./scheduler/service.py:8)، مقترنة باستبدال القاموس في [repository.py](./scheduler/repository.py:9). - التأثير: إنشاء خدمة باستخدام مستودع موجود قد يؤدي إلى إعادة استخدام المعرّف `1`، مما يؤدي إلى استبدال المهمة المخزنة وفقدان البيانات. - إعادة إنتاج الحد الأدنى: احفظ `Job(1, ...)`، وأنشئ `SchedulerService(repository)`، ثم أنشئ مهمة أخرى. قبل الإصلاح، بقيت المهمة الجديدة فقط. - الإصلاح: تهيئة المعرف التالي انطلاقًا من أعلى معرف موجود في المستودع. - اختبار التراجع: [test_scheduler.py](./tests/test_scheduler.py:22). 2. **متوسط — انحراف مواعيد التشغيل اليومية عند انتقالات التوقيت الصيفي** - الدليل: تصحيح الحساب في [time_rules.py](./scheduler/time_rules.py:4). - التأثير: تم تشغيل مهمة يومية مجدولة في الساعة 09:00 في الساعة 10:00 بعد انتقال التوقيت الصيفي في الربيع. - الحد الأدنى لإعادة التوليد: احسب موعد التشغيل التالي بعد `2026-03-07 09:00 America/New_York`. قبل الإصلاح، كانت النتيجة `2026-03-08 10:00`. - الإصلاح: إضافة يوم تقويمي محلي واحد بدلاً من 24 ساعة UTC المنقضية. - اختبار التراجع: [test_scheduler.py](./tests/test_scheduler.py:33). ## الملفات التي تم تغييرها - [scheduler/service.py](./scheduler/service.py) - [scheduler/time_rules.py](./scheduler/time_rules.py) - [tests/test_scheduler.py](./tests/test_scheduler.py) ## التحقق - لوحظ فشل كلا اختباري الانحدار قبل إصلاحهما. - اجتاز كل منهما الاختبار بعد الإصلاح المقابل. - `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v` - النتيجة: **اجتاز 4 اختبارات، 0 حالات فشل**. - لم يتبقَ أي آثار مخبأ لـ Python تم إنشاؤها. ## الاستنتاج والقرار - **الاستنتاج:** تم إصلاح العيوب المؤكدة وكلاهما مشمول باختبارات الانحدار المركزة. - **القرار المطلوب:** لا شيء.
عرض الناتج الكامل لرمز Claude
سجل التسليم الكامل، بما في ذلك النص الحرفي لأول ناتج صالح
سجل تشغيل # T4 — الاختبار ومراجعة الكود
معلمات تنفيذ ##
| الحقل | القيمة |
| --- | --- |
| المهمة | `T4` |
| موجه مجمد | `01-prompts/T4.md` |
| SHA-256 للموجه المجمد | `5e69546007ea776f40b3d334ddb75671ff684c151c77551bad27de3b0fdce640` |
| وحدة التنفيذ | وكيل فرعي معزول Claude، `للأغراض العامة`، سياق جديد |
| طريقة العزل | **الرجوع إلى الوكيل الفرعي** (تخفيض الإصدار الموثق — انظر `results/isolation-decision.md`) |
| النسخة النظيفة المخصصة | `runtime/workspaces/T4` |
| إصدار كود Claude | `2.1.220` |
| إعداد النموذج | `claude-opus-5` |
| start_utc | `2026-07-28T10:28:22Z` |
| end_utc | `2026-07-28T10:32:17Z` |
| المدة | 235 ثانية (متزامنة مع T1–T3؛ ليس قياسًا دقيقًا للكمون) |
| رقم المحاولة | 1 |
| الحالة | `صالح` |
| تدخل بشري | لا شيء |
تم حل الشرط الوارد في الموجه المجمد — "قم بإصلاحها إذا سمحت تكوينات التشغيل المجمدة
بإجراء إصلاحات" — بواسطة المنسق من ملف `00-control/run-config.json` و
`00-control/safety-policy.json`، اللذين يسمحان بكتابة نسخ معزولة من التجهيزات. تم إخطار المشغل
بأن الإصلاحات مسموح بها. ولم يُعرض عليه أي ملف تحكم.
## ملخص الأداة الآمنة
`date`، `قراءة`/`تحرير`/`كتابة` داخل مساحة العمل المخصصة فقط، `grep`،
`python3 -m unittest discover`، `python3 -m compileall`، تشغيل نسخة مؤقتة فارغة،
فحص وجود البيان. بدون شبكة، بدون تثبيتات، المكتبة القياسية فقط.
## الملفات التي تم تغييرها
`scheduler/time_rules.py` (تم تعديله)، `scheduler/service.py` (تم تعديله)،
`tests/test_scheduler.py` (تم تعديله، +2 اختبار)، `tests/test_time_rules.py` (تمت إضافته، 5 اختبارات).
التصحيح الكامل: `results/T4/patch.diff`.
## نتائج الفحص دون اتصال بالإنترنت
تم الإبلاغ عنها بواسطة مشغل المهام:
| الفحص | النتيجة |
| --- | --- |
| `python3 -m unittest discover -s tests -v` | **9 نجحت، 0 فشلت، 0 تم تخطيها** (الخط الأساسي 2) |
| `python3 -m compileall -q scheduler tests` | نجح |
| فحص وجود الملفات في قائمة البيانات مقابل `expected_files` | جميع الملفات الثمانية موجودة |
| تشغيل vacuity مقابل التنفيذات الأصلية المستعادة | 5 حالات فشل، 4 حالات نجاح، كما هو متوقع |
تم إعادة التحقق بشكل مستقل من قبل المنسق من خارج مساحة العمل:
| الفحص | الخروج | النتيجة |
| --- | --- | --- |
| مجموعة الاختبارات العامة (`results/checks/T4-public.txt`) | 0 | 9 اختبارات، OK |
فحص تقاطعي إعلامي، غير مُقيَّم: ينجح المُثبت الخفي T3 أيضًا في هذا
المساحة العمل (الخروج 0)، لأن T4 أصلح بشكل مستقل نفس عيب `next_daily_run`. انظر
`results/checks/validator-controls.md`.
## تغطية العيوب في الخريطة الذهبية
يُدرج ملف `03-checks/gold-map.json` عيبين لتقييم T4. تم العثور على كليهما:
| العيب المُدرج | تم العثور عليه | تم الإبلاغ عنه على أنه |
| --- | --- | --- |
| تم قبول مالك فارغ | نعم | **D5**، `scheduler/service.py:11,13`، درجة الخطورة منخفضة، تم الإبلاغ عنها ولم يتم إصلاحها عمدًا |
| حذف معرّف مفقود يثير `KeyError` | نعم | **D4**، `scheduler/repository.py:19` → `service.py:22`، درجة الخطورة متوسطة، تم الإبلاغ عنها ولم يتم إصلاحها عمدًا |
تم الإبلاغ عن ثلاث نتائج إضافية بخلاف المجموعة المزروعة. ولا يوجد أي منها نتيجة إيجابية خاطئة:
- **D1** — انحراف التوقيت الصيفي في `next_daily_run`. هذا هو العيب الثالث المدرج في
`03-checks/seeded-defects.md` (تم تصنيفه تحت T3، وليس T4، لكنه خطأ مزروع حقيقي).
- **D2** — المدخلات البسيطة في `next_daily_run` تحصل بصمت على المنطقة الزمنية للمضيف وتُرجع
تاريخًا ووقتًا مدركين لذلك. حقيقي ويعتمد على المضيف؛ تم التحقق منه بواسطة المنسق مقابل مصدر الاختبار.
- **D3** — تضارب في المعرفات بين خدمة ومستودع مُحقن أو مشترك، مما يتسبب في
الكتابة فوق البيانات بصمت. عيب حقيقي: تبدأ قيمة `SchedulerService._next_identifier` دائمًا من 1 بينما
تُعد `JobRepository.save` عملية تعيين لقاموس غير محمية. حددت T1 بشكل مستقل نفس
الخلل من التجهيز الأصلي.
عدد النتائج الإيجابية الخاطئة: **0**. كما أبلغ المشغل بشكل صحيح بعدم وجود أي نتائج أمنية، مشيرًا إلى
أن التجهيز لا يحتوي على أي سطح هجوم متعلق بالشبكة أو الإدخال/الإخراج أو إزالة التسلسل أو العمليات الفرعية أو بيانات الاعتماد.
## انحراف يستحق التسجيل
طلبت المطالبة المجمدة إجراء اختبارات وإصلاحات لـ "العيبين اللذين يتمتعان بأعلى درجة ثقة". اختار
المشارك D1/D2 (تصحيح واحد، نفس الوظيفة) وD3، بدلاً من العيبين المزروعين في الخريطة الذهبية
D4 وD5. والسبب المعلن مقبول: يعتمد كل من D4 وD5 على عقد واجهة برمجة تطبيقات (API) غير محدد،
لذا فإن إصلاحهما سيكون مجرد تخمين. لم يتأثر رصيد الكشف — فقد تم العثور على كلتا العيوبتين المزروعتين
، مع تحديد الملف والسطر ودرجة الخطورة والتأثير وإمكانية التكرار. كانت الإصلاحات المطبقة على عيوب حقيقية
ومدعومة بفحص الفراغ.
## أخطاء تم تصحيحها
فشلان في الاختبار ناتجان عن الخطأ الذاتي بسبب طرح "الوقت الفعلي" من "الوقت المطلق" في تواريخ وأوقات
تشترك في `tzinfo`؛ تم تصحيحهما وإعادة التحقق منهما. لا توجد أخطاء في الأدوات أو البيئة. تمت إزالة بقايا `__pycache__`
بعد التشغيل.
## المخرجات المرئية (حرفياً)
### تقرير العيوب
**D1 — `scheduler/time_rules.py:10-11` — انحراف الجدول اليومي بمقدار ساعة واحدة خلال التوقيت الصيفي — درجة الخطورة: عالية**
تضيف `next_daily_run` 24 ساعة *منقضية* عبر رحلة ذهاب وإياب بتوقيت UTC بدلاً من تقديم اليوم التقويمي. يتم تحديد المهمة اليومية حسب الوقت الفعلي، لذا فإن كل مهمة في منطقة تطبق التوقيت الصيفي يتم تشغيلها بصمت قبل أو بعد ساعة واحدة من يوم الانتقال فصاعدًا، ويستمر الخطأ (يتم إعادة ضبط كل تشغيل من الوقت الذي تم تغييره). وقد اعترف نص التوثيق نفسه بهذا السلوك.
```
prev = datetime(2024, 3, 9, 9, 0, tzinfo=ZoneInfo('America/New_York'))
next_daily_run(prev) # -> 2024-03-10 10:00:00-04:00، المتوقع 09:00-04:00
prev = datetime(2024, 11, 2, 9, 0, tzinfo=ZoneInfo("America/New_York"))
التشغيل اليومي التالي (السابق) # -> 2024-11-03 08:00:00-05:00، المتوقع 09:00-05:00
```
**D2 — `scheduler/time_rules.py:10-11` — المدخلات البسيطة تحصل بصمت على المنطقة الزمنية المحلية للجهاز — درجة الخطورة: متوسطة**
نفس السطرين. `.astimezone(timezone.utc)` على تاريخ ووقت بسيط يفترض التوقيت المحلي للنظام، و`.astimezone(None)` تُرجع تاريخًا ووقتًا مدركًا. تُرجع الدعوة التي تدخل بقيمة بسيطة قيمة واعية عند الخروج، لذا فإن النتيجة غير قابلة للمقارنة مع القيم البسيطة الأخرى للمستدعي (`TypeError` عند المقارنة) ويعتمد الجواب على `TZ` للمضيف.
```
next_daily_run(datetime(2024, 1, 1, 9, 0))
# -> datetime(2024, 1, 2, 9, 0, tzinfo=timezone(timedelta(hours=8), "CST")) # يعتمد على المضيف
```
**D3 — `scheduler/service.py:8,13,15` (البادئة) — تضارب المعرفات يؤدي إلى إتلاف المهام المخزنة دون إشعار — درجة الخطورة: عالية**
كان عداد المعرفات خاصًا بكل `SchedulerService` ويبدأ دائمًا من 1، متجاهلًا محتويات المستودع المُدرج. أي خدمة ثانية تستخدم مستودعًا مشتركًا، أو أي خدمة تستخدم مستودعًا مُعبأً مسبقًا، تعيد إصدار المعرّف 1؛ `JobRepository.save` هي عملية تعيين لقاموس، لذا تم استبدال المهمة الموجودة دون ظهور أي خطأ. فقدان البيانات.
```
repo = JobRepository()
SchedulerService(repo).create_job("النسخ الاحتياطي الليلي", "Alex") # المعرف 1
SchedulerService(repo).create_job('Payroll export', 'Blake') # id 1 مرة أخرى
repo.all() # -> [Job(1, "Payroll export", "Blake")] — اختفت مهمة أليكس
```
**D4 — `scheduler/repository.py:19` → `scheduler/service.py:22` — تثير `delete_job` استثناء `KeyError` بسبب معرّف غير معروف — درجة الخطورة: متوسطة**
تستخدم `delete` `dict.pop` بدون قيمة افتراضية، في حين أن الدالة الشقيقة `get` (السطر 13) تعيد `None` في حالة عدم وجود العنصر. يؤدي هذا التناقض إلى تسرب استثناء `KeyError` خام عبر `SchedulerService.delete_job`، وهو ما من غير المرجح أن يلتقطه المستدعون. إعادة التمثيل: `SchedulerService().delete_job(999)` → `KeyError: 999`. يمكن إصلاح ذلك باستخدام `pop(identifier, None)` أو استثناء مجال صريح — تم تركه دون إصلاح عمدًا، نظرًا لأن العقد الصحيح (عدم تنفيذ العملية بصمت مقابل خطأ محدد النوع) هو قرار يتعلق بواجهة برمجة التطبيقات (API) يخص المالك.
**D5 — `scheduler/service.py:11,13` — حقل 'owner' غير مُتحقق من صحته — درجة الخطورة: منخفضة**
يتم التحقق من أن `name` فارغًا ولكن لا يتم التحقق من `owner`: `create_job('ok', ' ')` يخزن `owner=''`. كما أن كلا المعلمتين تستدعيان `.strip()` دون حماية، لذا يظهر `None` على أنه `AttributeError: الكائن 'NoneType' لا يحتوي على السمة 'strip'` بدلاً من `ValueError` الذي تستخدمه واجهة برمجة التطبيقات (API) عادةً في حالة الإدخال الخاطئ. تُركت دون إصلاح — لم يُذكر العقد المقصود للمالك في أي مكان في الأداة.
**الأمان:** لم يتم العثور على أي مشكلات. لا يحتوي البرنامج المساعد على أي واجهة للشبكة أو الإدخال/الإخراج أو إزالة التسلسل أو العمليات الفرعية أو بيانات الاعتماد؛ والتخزين عبارة عن قاموس داخل العملية.
**فجوة في التغطية:** لم تكن هناك تغطية اختبارية لـ `scheduler/time_rules.py` و`scheduler/repository.py` قبل هذا التشغيل؛ حيث لم يختبر الاختباران المُعدان مسبقًا سوى المسار السليم للخدمة.
### الاختبارات والإصلاحات المطبقة
كان العيبان اللذان حظيا بأعلى درجة ثقة هما **D1/D2** (نفس الدالة، إصلاح واحد) و**D3**.
**التصحيح 1 — `scheduler/time_rules.py`:** تم استبدال رحلة الذهاب والإياب إلى التوقيت العالمي المنسق (UTC) بـ `previous_run + timedelta(days=1)`. تقوم لغة Python بإجراء العمليات الحسابية وفقًا للوقت الفعلي (wall-clock) على التواريخ والأوقات المُدركة، وتقوم `zoneinfo` بإعادة تحديد إزاحة التوقيت العالمي المنسق (UTC) بشكل مؤجل استنادًا إلى الوقت الفعلي الجديد — لذا تظل الساعة 09:00 هي 09:00 بينما تتحرك الإزاحة بشكل صحيح من `-05:00 → -04:00`. يؤدي هذا إلى إصلاح D1 و D2 معًا: تظل المدخلات البسيطة بسيطة الآن ولا يتم استنتاج المنطقة المحلية أبدًا. تم توثيق حالة ساعة الانتقال «غير القابلة للوصول مقابل الغامضة» على أنها تخضع لقواعد الطي في tzinfo.
**الإصلاح 2 — `scheduler/service.py`:** تمت إزالة عداد `_next_identifier` الخاص بكل مثيل؛ ويتم الآن تخصيص المعرفات من حالة المستودع على النحو التالي: `max(المعرفات الموجودة، الافتراضي=0) + 1` عند وقت الإنشاء. وهذا صحيح لكل من المستودعات المشتركة والمستودعات المعبأة مسبقًا. المقايضة: O(n) لكل عملية إنشاء بدلاً من O(1)، وهو أمر مقبول لمخزن في الذاكرة مدعوم بقاموس (dict)، ويضمن الدقة مقارنةً بعداد لا يمكنه رؤية المخزن الذي يكتب إليه.
**الاختبارات — `tests/test_time_rules.py` (جديد، 5 اختبارات):** الحفاظ على التوقيت الفعلي في حالات التقدم في الربيع والتراجع في الخريف، والوقت المطلق المنقضي البالغ 23 ساعة/25 ساعة عبر تلك الانتقالات، وإعادة تحديد إزاحة التوقيت العالمي المنسق (UTC)، و«البقاء على البساطة» (naive-stays-naive)، والتقدم اليومي البسيط في التوقيت العالمي المنسق (UTC). يتم تخطي الاختبار بشكل سلس في حالة عدم وجود قاعدة بيانات IANA.
**الاختبارات — `tests/test_scheduler.py` (موسعة، +2 اختبار):** يجب على خدمتين تشتركان في مستودع واحد إصدار معرّفات مميزة والاحتفاظ بكلتا المهمتين؛ ويجب على الخدمة التي تعمل على مستودع مملوء مسبقًا بالمعرّفين 1 و7 إصدار المعرّف 8 وترك المهام الموجودة كما هي.
**فحص الفراغ:** قمت باستعادة كلا التنفيذين الأصليين في نسخة مؤقتة وأعدت تشغيل مجموعة الاختبارات — فشلت جميع الاختبارات الخمسة الجديدة (`FAILED (failures=5)`)، ونجحت جميعها مع الكود الذي تم إصلاحه. تثبت الاختبارات وجود العيوب بشكل قاطع.
تصحيح واحد أثناء التشغيل: كانت مسودتي الأولى تؤكد الوقت المنقضي في التوقيت الصيفي (DST) على أنه `result - previous`، وهو ما يقيّمه لغة Python كحساب على أساس الساعة الحقيقية عندما يشترك كلا المعاملين في نفس tzinfo، لذا قرأته على أنه `24h` وفشلت الاختبارات. يتم الآن تحويل التأكيدات إلى توقيت UTC قبل الطرح. كان الفشل في الاختبار الخاص بي، وليس في الإصلاح.
### ملاحظات للمالك
لم يتم تغيير ملف `fixture-manifest.json`، لذا فإن ملف `tests/test_time_rules.py` هو ملف جديد صحيح غير مدرج في `expected_files` — قم بتحديث ملف البيان إذا كانت هناك عملية فحص تفرض مجموعة ملفات محددة بدقة. وقد تم الإبلاغ عن D4/D5 ولكن لم يتم إصلاحهما عمدًا: كلاهما يعتمدان على قرار يتعلق بعقد واجهة برمجة التطبيقات (دلالات «miss-on-delete»، وقواعد التحقق من صحة المالك) غير محدد في أي مكان في التجهيز، لذا فإن اختيار أحدهما كان سيكون مجرد تخمين وليس إصلاحًا.
قيود النظام: كان هذا مستودعًا صغيرًا لـ Python يعمل دون اتصال بالإنترنت. استخدم Claude وكيلًا فرعيًّا كحل بديل بعد انتهاء صلاحية OAuth عبر واجهة سطر الأوامر (CLI)، لذا لم تكن العزل ورؤية الرمز المميز متطابقتين.
لا يُلغي أي من هذين التقييمين الحاجة إلى المراجعة البشرية. بعد أن ينتهي أي من الوكلاء من إجراء الإصلاح، يجب فحص الواجهات التي تم تغييرها، ونطاق الملفات غير المتوقع، والاختبارات السلبية المفقودة، وسجل الأذونات أو الأوامر، ومسار التراجع. فالتفسير المقنع لا يُعد بديلاً عن الاختبار القابل للتكرار.
الأذونات، وبيئة الحماية، والسلامة التشغيلية
يمكن لوكيل البرمجة قراءة الكود الخاص، وتنفيذ أوامر شل، وتعديل العديد من الملفات، واستدعاء أدوات خارجية. وهذا يجعل تصميم الأذونات جزءًا من جودة المنتج. والأسئلة ذات الصلة هي: ما هي العمليات التي تتطلب موافقة؟ وما الذي يمكن للوكيل الوصول إليه بشكل افتراضي؟ وما مدى وضوح التحذير المسبق بشأن الإجراءات المحفوفة بالمخاطر؟ وهل يمكن للمطور فحص التغييرات الناتجة؟.
لا تعتبر أن تقليل عدد مطالبات الموافقة يعني بالضرورة أن النظام أفضل. فالتقليل من العقبات مفيد في بيئة معزولة لا تتضمن بيانات اعتماد أو اتصالات بالإنتاج. لكن السلوك نفسه قد يكون خطيرًا في مستودع مرتبط ببرامج نصية للنشر، أو ببيانات عملاء حقيقية، أو بأذونات سحابية واسعة النطاق. وعلى العكس من ذلك، فإن الإفراط في طلبات الموافقة قد يجعل الأتمتة الآمنة غير عملية، ويشجع المستخدمين على الموافقة على الطلبات دون قراءتها.
استخدم اختبارنا نسخًا محلية حديثة، دون اللجوء إلى أنظمة الإنتاج أو عمليات النشر، ودون أي تدخل بشري في عمليات التشغيل الفعلي. وبالتالي، فإنه يقيّم إنجاز المهام في ظل ظروف آمنة، وليس مستوى الأمان النسبي للمنتجين. قبل استخدام أي من هاتين الأداتين في أعمال مهمة، ابدأ بالوصول للقراءة فقط، وحدد الدلائل والأوامر المسموح بها، وراجع الفروق، وقم بإجراء فحوصات موضوعية في بيئة قابلة للاستعادة.
- ابدأ ببنية «للقراءة فقط» أو خذ المخاطرة.
- لا توافق إلا على الأوامر التي تفهم نطاقها ونتائجها.
- احرص على الاحتفاظ ببيانات الاعتماد وبيانات الإنتاج ووصول النشر خارج نطاق الإصدار التجريبي.
- اشترط وجود ملف «diff» واختبارات ومسار تراجع واضح قبل قبول النتيجة.
MCP، والمهارات، وتعليمات المشروع، والتخصيص
يمكن توسيع كلا النظامين البيئيين، لكن لا ينبغي اعتبار مصطلحي «التوسيع» و«الامتداد» مترادفين. فالتعليمات الخاصة بالمشروع ترشد الوكيل إلى كيفية التصرف داخل المستودع. أما «المهارات القابلة لإعادة الاستخدام» فهي عبارة عن حزمة تضم سير عمل قابل للتكرار أو خبرة معينة. ويقوم «MCP» بربط المضيف بالأدوات أو البيانات الخارجية. ويمكن لـ«الخطافات» و«الأوامر» أتمتة مراحل معينة في دورة التطوير. يمكن أن يكون المنتج قويًّا في طبقة ما دون أن يطابق ميزة أخرى بشكل تام.
السؤال الأساسي عند الشراء ليس ما إذا كان شعار التكامل موجودًا أم لا، بل ما إذا كان من الممكن تثبيت الاتصال وتوثيقه والموافقة عليه وتشغيله في النظام المضيف الذي تستخدمه فعليًّا. كما يجب أن يتضمن نمط فشل يمكن فهمه. يظل خادم MCP الذي يعمل بشكل تفاعلي ولكنه ينتظر الموافقة في جلسة غير مراقبة مفيدًا، ولكن لا ينبغي وصفه بأنه أتمتة خالية من العوائق.
تنطبق نفس الملاحظة على التعليمات القابلة لإعادة الاستخدام. فملفات التعليمات الطويلة لا تضمن الامتثال، كما أن مجموعة القواعد المفرطة في التعقيد قد تحجب السياق أو تؤدي إلى تناقضات. لذا، يجب أن تكون إرشادات المستودع موجزة وقابلة للاختبار ومرتبطة بشكل وثيق بالكود. وذُكر فيها أوامر التحقق المطلوبة، والمناطق المحمية، وقواعد الأسلوب، واللحظات التي يجب على الوكيل فيها التوقف لطلب التوجيه.
- تعليمات المشروع: القواعد الخاصة بالمستودع وأوامر التحقق.
- المهارات: إجراءات قابلة لإعادة الاستخدام أو حزم الخبرات.
- MCP: الربط بالأدوات والبيانات الخارجية.
- الخطافات والأوامر: الأتمتة حول أحداث محددة في سير العمل.
كوديكس مقابل Claude: الأسعار وحدود الاستخدام
تبدأ مقارنة باقات المستهلكين الأساسية من $20 شهريًّا. ويشمل ذلك الوصول إلى Codex من خلال باقة $20 ChatGPT ذات الصلة، في حين تبلغ تكلفة باقة Claude Pro $20 شهريًّا في الولايات المتحدة وتشمل Claude Code. تقدم كلتا الخطتين مستويات استهلاك أعلى بسعر $100 و$200. ولا تعني الأسعار المعلنة المتشابهة أن السعة متطابقة.
تبلغ تكلفة باقة “Claude Max 5x” $100 شهريًّا، بينما تبلغ تكلفة باقة “Max 20x” $200 شهريًّا. تشير التسميتان «5x» و«20x» إلى الاستخدام لكل جلسة مقارنةً بإصدار Pro، وليس إلى عدد مضمون من مهام البرمجة. يتشارك كل من Claude وClaude Code الحدود المسموح بها لكل جلسة والأسبوعية. وقد يؤثر طول السياق والملفات المرفقة واختيار النموذج واستخدام الميزات على سرعة استهلاك الحصة المسموح بها.

يمكن أن تسمح أرصدة الاستخدام الاختيارية لـ Claude بمواصلة الأعمال المؤهلة بعد استنفاد الاستخدام المشمول في الباقة عند تفعيلها، ويتم احتساب تكلفة هذه الأرصدة بشكل منفصل وفقًا لأسعار واجهة برمجة التطبيقات (API) القياسية. وتعد مصادقة مفتاح واجهة برمجة التطبيقات (API) مسارًا آخر منفصلاً للفوترة. إن وصف أي من هذين المسارين بـ “غير محدود” من شأنه إخفاء التكلفة الهامشية الفعلية.

كما يقوم «Codex» بفصل استخدام خطط المستهلكين المضمنة، والرصيد المشتراة المؤهلة، وفواتير واجهة برمجة التطبيقات (API). وتشترك الرسائل المحلية والمحادثات السحابية في نافذة زمنية مدتها خمس ساعات، وقد تنطبق أيضًا حدود أسبوعية. ولا يمكن تحويل حقل الرمز المميز الموجود في سجل واجهة سطر الأوامر (CLI) مباشرةً إلى نسبة مئوية ضمن نافذة الخمس ساعات، أو مبلغ رصيد الاشتراك، أو فاتورة واجهة برمجة التطبيقات (API).
بالنسبة لأعمال البرمجة الفردية التي تتم من حين لآخر، تُعد فئة $20 على أي من الجانبين نقطة انطلاق معقولة. قد يبرر العمل اليومي على المستودعات في سياقات طويلة اختيار فئة استخدام أعلى، ولكن فقط بعد مراقبة عمليات إعادة التعيين الفعلية واستهلاك المهام. أما العمل المتوازي المكثف فيحتاج إلى مزيد من العناية: فالدفع مقابل فئة أكبر لا يلغي الحاجة إلى التحكم في السياق، وتقسيم المهام، وحجز عمليات الاستدلال المكلفة للأعمال التي تتطلب درجة عالية من التقدير.
ما توصل إليه اختبارنا المقارن بين كوديكس وClaude
قمنا بتثبيت أربعة أسئلة باللغة الإنجليزية، ومكتبة Python عامة، واختبارات موضوعية، ومعيار تقييم، وقاعدة «أول نتيجة صحيحة» قبل تشغيل أي من الوكلاء. وشملت المهام فهم مستودع غير مألوف، وميزة متعددة الملفات، وإصلاح خطأ في التوقيت الصيفي (DST)، ومراجعة الكود مع إجراء التصحيحات. لم تخضع النتائج الصحيحة لأي تدخل بشري، ولم يكن بالإمكان إعادة تشغيل المخرجات الضعيفة ولكن الصحيحة للحصول على درجة أفضل.
قام «Codex» بتشغيل عمليات CLI معزولة مع الاحتفاظ ببيانات JSONL الأولية وحقول الرموز التي أصدرتها CLI. وكانت جلسة OAuth الخاصة بـ«Claude CLI» الخاصة بالزميل قد انتهت صلاحيتها، لذا استخدم «Claude Code» منسقًا مع سياقات وكلاء فرعيين جديدة. أعدنا بناء تصحيحات Claude في نسخ تدقيق نظيفة وأعدنا تشغيل الفحوصات العامة والمخفية. وقد أسفر ذلك عن أدلة عملية موثوقة، ولكن لم ينتج عنه عزل متطابق أو أسطح تحكم نموذجية متطابقة.
| المهمة | كودكس | كلود كود | التفسير المحدود |
|---|---|---|---|
| T1: فهم المستودع | 20/20 | 20/20 | تعادل؛ النهج الموجز مقابل النهج الشامل |
| T2: ميزة دعم الملفات المتعددة | 30/30 | 30/30 | الارتباط الوظيفي؛ اختلاف نطاق التحقق والاختبار |
| T3: إصلاح نظام التوقيت الصيفي | 30/30 | 30/30 | كلاهما نجح؛ رقعة أضيق مقابل تغطية أوسع للحواف |
| T4: المراجعة والإصلاح | 18/20 | 19/20 | أظهر الرمز Claude نطاقًا أوسع للمراجعة |
اختبار خاضع للرقابة · معايير التقييم المحددة مسبقًا
كودكس 98/100 مقابل Claude كود 99/100
الفارق بنقطة واحدة لا يُعد إشارة مؤكدة على الفوز. فالاختلافات المفيدة تختلف باختلاف المهمة.
| مجال اتخاذ القرار | النتيجة الملاحظة | القراءة العملية |
|---|---|---|
| فهم المستودع | تعادل · 20/20 لكل منهما | كان Claude أكثر شمولاً؛ أما «كودكس» فكان أكثر إيجازاً. |
| ميزة الملفات المتعددة | تعادل · 30/30 لكل منهما | اجتاز كلاهما الاختبارات الخفية؛ وأجرى Claude اختبارات أكثر شمولاً. |
| إصلاح الخلل المتعلق بالتوقيت الصيفي | تعادل · 30/30 لكل منهما | غطى Claude حوافًا أكثر؛ بينما استخدم «كودكس» الرقعة الأضيق. |
| الفحص والإصلاح | Claude 19/20؛ المخطوطة 18/20 | وقد كشفت تقنية Claude عن المزيد من العيوب القابلة للتكرار. |
| السرعة المقاسة | مختلط | Claude قاد T1/T2؛ كوديكس قاد T3/T4. |
إفصاح: نفس المطالبات والتركيبات، ولكن مسارات عزل مختلفة. لا تقم بتعميم هذا الاختبار الصغير على كل مستودع أو طبقة نموذج أو جلسة مستقلة.
هذا الاختبار صغير جدًّا بحيث لا يمكن الاعتماد عليه لتقييم الأداء في المستودعات الكبيرة، أو في جميع اللغات، أو في جميع مستويات النماذج، أو في الجلسات المستقلة الطويلة. ومن الأفضل تفسير الفارق الإجمالي البالغ نقطة واحدة على أنه “نجح كلاهما، مع اختلاف في نطاق المراجعة”، وليس على أنه ترتيب شامل.
ما يذكره المستخدمون الحقيقيون — وإلى أي مدى يمكن الوثوق به
تكون تعليقات المجتمع ذات قيمة عندما تتضمن مشروعًا أو مهمة أو نموذجًا أو سياقًا للجهد أو أفقًا زمنيًا. وتكون ضعيفة عندما يقتصر المنشور على الإشارة إلى أن منتجًا ما “يبدو أكثر ذكاءً” أو “أسرع بكثير”. ويقوم مستخدمون مختلفون بمقارنة مستودعات مختلفة، ومستويات اشتراك مختلفة، ومطالبات مختلفة، وملحقات مختلفة، ومستويات إشراف مختلفة.
يشير المثال السياقي المأخوذ من موقع Reddit أعلاه إلى وجود مفاضلة في التفاعل: فالسرعة والطابع الحواري قد يتطلبان مزيدًا من الانتباه، في حين أن التنفيذ المدروس قد يبدو أبطأ ولكنه يتطلب تصحيحات أقل. لا يتطابق اختبارنا الخاضع للرقابة إلا جزئيًا مع ذلك الحساب. فقد أظهر الاختبار سرعات متفاوتة وغياب التدخل البشري في التجارب الصالحة، لذا لا يمكنه تأكيد صحة الادعاء المتعلق بـ«المراقبة». وهذا بالضبط هو السبب الذي يجعل من الضروري عرض أدلة المجتمع والأدلة الخاضعة للرقابة معًا دون دمجهما.
يثير التعليق المتعلق بـ«X harness» نقطة مفيدة ثانية: إن نتيجة البرمجة تنتمي إلى النظام بأكمله، وليس فقط إلى تسمية النموذج. ولا ينبغي التعامل مع أي من المنشورين على حدة باعتبارهما بيانات استطلاعية. استخدمهما لتحديد الأسئلة الخاصة بتجربتك الخاصة — عدد التدخلات، وحجم الفرق، وجودة الاختبار، والتعافي من الافتراض الخاطئ.
توسيع نطاق كودكس ورمز Claude ليشمل GlobalGPT
GlobalGPT هو مساحة عمل متعددة النماذج ومتعددة الوسائط, ، ولا يُعد بديلاً عن وكلاء المستودع الأصليين. ويتمثل دوره العملي في توسيع نطاق المضيف الحالي: استخدام نموذج وكيل آخر متاح للحصول على رأي ثانٍ أو مراجعة الخطة أو إتمام التوثيق أو إنتاج مخرجات متخصصة، بينما يظل كل من Codex أو Claude Code مسؤولين عن الوصول إلى المستودع وأوامر شل والاختبارات والموافقات.
تنشر GlobalGPT أدلة CLI الخاصة بها لـ كودكس و كلود كود, ، بالإضافة إلى Cursor. في اختبار التكامل الآمن T5 الذي أجريناه، أنجزت واجهة سطر الأوامر (CLI) المهمة «المجمدة» نفسها في كلتا البيئتين المقارنتين. وفي Codex، تحققنا أيضًا من استدعاء قائمة نماذج MCP للقراءة فقط، وقمنا بتثبيت مهارة GlobalGPT وتحميلها واستخدامها.
تكامل GlobalGPT · مستبعد من درجة الترميز
تم التحقق من CLI في كلا مساري العمل؛ وتم التحقق من MCP وSkill في Codex
يقيس هذا مسارات التكامل، وليس ما إذا كان GlobalGPT يحل محل أي من عوامل الترميز الأصلية.
| المسار | بيئة Codex | سباق Claude الذي نظمه الزملاء |
|---|---|---|
| GlobalGPT CLI | تم التحقق باستخدام gpt-5.6-sol و gpt-5.6-luna | تم التحقق منها باستخدام نفس المهام المجمدة |
| MCP | تم التحقق من قائمة النماذج التفاعلية المخصصة للقراءة فقط | لم يكن متصلاً أثناء التشغيل |
| المهارة | تم تركيبها وتحميلها واختبارها | تم تثبيته ولكن لم يُستخدم في المكالمات المجمدة |
| MCP غير المراقب | تم ملاحظة وجود قيود على الموافقة | لم يتم اختباره |
عرض الأدلة الكاملة على التكامل
ملخص اختبار التكامل # GlobalGPT نطاق ## يقيس الاختبار T5 تكامل GlobalGPT، وهو مستبعد من درجة الترميز الأصلية في Codex. لم يتم استخدام Yukie. ## قفل النموذج وجاهزيته - النموذج أ: `gpt-5.6-sol` - النموذج ب: `gpt-5.6-luna` - ظهر كلا النموذجين في قائمة النماذج الحية. - أعادت كلتا اختبارات الجاهزية الخفيفة نصًا صالحًا وقابلًا للتحليل. - تم قفل النموذجين قبل استدعاءات الإخراج الرسمية لـ T5A و T5B. ## نتائج CLI الرسمية | المهمة | النموذج | الحالة | المدة | رموز المطالبة | رموز الإكمال | العناوين المطلوبة | |---|---|---|---:|---:|---:|---:| | T5A | gpt-5.6-sol | صالحة | 27 ثانية | 2,116 | 1,207 | 6/6 | | T5B | gpt-5.6-luna | صالحة | 14 ثانية | 2,116 | 1,441 | 6/6 | استخدمت كلتا الدعوتين الرسميتين نفس مهمة تخطيط المنتج باللغة الإنجليزية المجمدة من خلال `glbgpt exec`، وأرجعتا مخرجات مرئية باللغة الإنجليزية فقط، ولم تكشفا عن أي بيانات اعتماد. لم تحدث إعادة تشغيل للتحقق من الجودة. ## نتيجة MCP - أظهر `codex mcp list` أن `globalgpt` ممكّن. - اكتشفت جلسة Codex غير تفاعلية `mcp__globalgpt__glbgpt_list_models` وحاولت تنفيذها، لكن تم إلغاء الاستدعاء بسبب عدم توفر موافقة MCP غير المراقبة. لم يتم تخفيف أي إعدادات أمان. - نجحت جلسة Codex التفاعلية النشطة في استدعاء أداة MCP GlobalGPT نفسها المخصصة للقراءة فقط، وتلقت تسعة نماذج دردشة. - النتيجة: تم التحقق من الوصول التفاعلي إلى MCP؛ بينما يظل التنفيذ غير التفاعلي غير المراقب لـ MCP خاضعًا لقيود الموافقة. نتيجة مهارة ## - تم تثبيت مهارات البرمجة GlobalGPT وGlobalGPT في دليل مهارات Codex من خلال روابط إلى حزمة مهارات CLI المجمعة. - تم تحميل مهارة GlobalGPT ومتابعتها للتحقق من الجلسة المُهيأة، واختيار النموذج المباشر، والجاهزية، وخيارات الأمان الائتماني، ومعالجة الأعطال. - النتيجة: تم تثبيتها وتجربتها في سير عمل Codex النشط. ## استنتاج محدود يتحقق هذا التشغيل من عمل استدعاءات CLI الخاصة بـ GlobalGPT، واستدعاء تفاعلي للقراءة فقط لـ GlobalGPT MCP من Codex، ومسار مهارة GlobalGPT تم تثبيته واستخدامه. ولا تثبت هذه العملية أن كل نموذج أو أداة وسائط أو مضيف أو حساب أو تكوين MCP غير خاضع للإشراف يعمل. كما أنها لا تختبر Yukie ولا تدعم الادعاء بأن GlobalGPT يحل محل Codex أو Claude Code.
النطاق الذي تم التحقق منه: استدعاءات محددة لواجهة سطر الأوامر (CLI)، وعملية قراءة تفاعلية واحدة عبر MCP، ومسار واحد لمهارة تم تثبيتها/استخدامها. ولا يُثبت هذا التحقق صحة كل نموذج أو أداة وسائط أو مضيف أو تكوين غير خادم.
الحدود مهمة. فقد أثبتت عملية تشغيل Claude التي أجراها الزميل صحة مسار CLI، وليس MCP من جانب Claude. كانت «المهارة» مثبتة هناك، لكنها لم تُستخدم في المكالمات المجمدة. لا تزال محاولة Codex MCP غير المراقبة تتطلب موافقة يدوية. كما يعتمد توفر النماذج والرصيد على خطة GlobalGPT الحالية، لذا يجب على المطورين التحقق من القائمة الحالية بدلاً من افتراض أن كل نموذج مشمول.
يغطي GlobalGPT أيضًا الصور والفيديو والصوت وسير عمل الوكيل الموجه. تندرج إدخالات «الشرائح» و«المستندات» و«الصور» في Yukie ضمن فئة مختلفة: فهي توفر قوالب واضحة وإرشادات خطوة بخطوة عبر المتصفح للمهام التي لا تتطلب كتابة كود. وقد يكون ذلك أسهل من فتح واجهة سطر الأوامر (CLI) لكتابة كود من أجل إنشاء عرض تقديمي أو مستند منظم، لكنه لا يحل محل قراءة المستودع أو تنفيذ الاختبارات أو مراجعة الكود.
فئة مختلفة من سير العمل
اختبارات وكيل المتصفح التي أدارتها يوكي
مفيد في سير العمل على الويب المخصص لمهام محددة؛ لم يتم اختباره كبديل لوكيل البرمجة في المستودع.
| سير العمل | تم استيفاء المعايير | أول نتيجة صحيحة |
|---|---|---|
| الشرائح | 5/6 | تم إنشاء عرض تقديمي مكون من خمس شرائح؛ ولم يتسن التحقق من ملاحظات المتحدث. |
| وثيقة | 6/6 | ملخص بحثي منظم يتضمن ميزات التصدير وسجل الإصدارات. |
| الصورة + التعليق | 5/6 | صورة مربعة واضحة؛ لكن التعليق المطلوب كان مفقودًا. |
استنتاج صحيح: نقاط دخول واضحة وسير عمل متعدد الوسائط موجه. استنتاجات غير مدعومة: الاستخدام غير المحدود، أو السعر المحدد، أو الاستبدال الكامل لرمز Codex/Claude.
ما هو أداة البرمجة التي ينبغي للمطور المستقل أن يختارها؟
- اختر «كودكس» عندما يتناسب التنفيذ المحدود المدمج، أو مزيج الأسطح المتاحة فيه، أو أدلة التشغيل المتوفرة في إعداداتك، مع أسلوب عملك.
- اختر الرمز Claude عندما تكون حلقة المحطة التخاطبية، أو ميزات التخصيص التي قمت بالتحقق منها، أو سلوك المراجعة الأوسع نطاقًا مثل ذلك الذي لوحظ في أداة الاختبار الخاصة بنا، هي الأمور الأكثر أهمية.
- استخدم أيًّا منهما في حالة وجود مستودع غير مألوف فقط بعد اجتياز اختبار بنية «للقراءة فقط» واختبار المخاطر. وقد أدت كلتا الأداتين هذه المهمة بشكل جيد.
- استخدم كليهما بشكل انتقائي متى يكون إجراء مراجعة بواسطة وكيل ثانٍ يستحق تكلفة الاشتراك والتنسيق الإضافية. اطلب من الأداة الثانية أن تراجع الفروق أو الخطة بدلاً من تكرار المهمة دون تفكير.
- أضف GlobalGPT عندما تكون عملية التوجيه متعدد النماذج أو العمل متعدد الوسائط هي الطبقة المفقودة. احتفظ بعمليات المستودع الأصلية في مضيف البرمجة.
تعد الفترة التجريبية التي مدتها سبعة أيام أكثر إفادة من لوحة المتصدرين. اختر ميزة حقيقية واحدة غير متعلقة بالإنتاج، وخطأً واحداً، وقم بمراجعتها. قم بتجميد الأمر الفوري وأمر النجاح. سجل أول فرق صالح، والاختبارات التي تم اجتيازها، والوقت المنقضي، والتدخلات البشرية، والنطاق غير المتوقع، وكيف أثر العمل على الاستخدام المتاح لديك. المنتج الأفضل هو الذي يمكنك اكتشاف أخطائه والحفاظ على سير عمله.
الأسئلة الشائعة حول كود «Codex» مقابل كود «Claude»
هل نظام «كوديكس» أفضل من نظام «Claude»؟
ليس بشكل عام. فقد أنجز كلاهما المهام الأربع الواردة في برنامج الاختبار الخاص بنا. وتفوق كود Claude في نطاق المراجعة، في حين كان كودكس أكثر إيجازًا في بعض جوانب التنفيذ وإصلاح الأخطاء.
أيهما أفضل للمستودعات الكبيرة؟
لا يمكن لبرنامجنا الصغير الإجابة على هذا السؤال. قم بتقييم كليهما في مهمة بنية «للقراءة فقط» من مستودعك الخاص قبل السماح بإجراء أي تغييرات.
أي عامل ترميز يتطلب إشرافًا أقل؟
يعتمد ذلك على وضوح المهمة، وإعدادات النموذج، وتعليمات المستودع، وأسلوب التفاعل المطلوب. وقد أشار أحد مستخدمي موقع Reddit إلى أنماط إشراف مختلفة، لكن تلك التجربة الفردية لا تمثل قاعدة عامة تنطبق على المنتج بأكمله.
أيهما أرخص؟
تتوافق مستويات الاستهلاك الرئيسية عند $20 و$100 و$200 شهريًّا، لكن السعة المضمنة وآليات تحديد الحدود تختلف. أما الائتمانات الاختيارية والفوترة عبر واجهة برمجة التطبيقات (API) فهي منفصلة.
هل تتشارك خطتا Claude وClaude في حدود الاستخدام؟
نعم. يستخدم كل من Claude و«Claude Code» حدودًا مشتركة للجلسات وحدودًا أسبوعية في باقات Pro أو Max المرتبطة بهما.
هل تتشارك مهام Codex المحلية والسحابية في نفس الحدود؟
تشترك الرسائل المحلية والمحادثات السحابية في فترة زمنية مدتها خمس ساعات، وقد تُطبق أيضًا حدود أسبوعية.
هل يمكن أن يحل طراز GlobalGPT محل طراز Codex أو Claude Code؟
لا. يمكنه توسيع نطاق أي من مساري العمل بإضافة نماذج إضافية، وواجهة سطر الأوامر (CLI)، وMCP، والمهارات، والأدوات متعددة الوسائط، لكن الوصول إلى المستودع وسلوك وكيل البرمجة يظلان في النظام المضيف.
هل يمكنني استخدام الرمز GlobalGPT من كلا المنتجين؟
يوفر GlobalGPT دروسًا تعليمية رسمية حول واجهة سطر الأوامر (CLI) لكليهما. وقد تحققنا من استخدام واجهة سطر الأوامر في كلتا البيئتين، وكذلك من استخدام MCP وSkill في Codex، مع وجود قيود على الموافقة فيما يتعلق بـ MCP غير المراقب.
تم التحقق من الأسعار وقواعد الباقات وعمليات التكامل ومصادر الأدلة في يوليو 2026. قد تتغير تفاصيل المنتج.
افتتاح GlobalGPT إذا كنت ترغب في إضافة طبقة متعددة النماذج ومتعددة الوسائط إلى سير عمل الترميز الحالي لديك.


