---
name: gas-pipeline
description: أنبوب implement→gate→review→PR→دمج تلقائي→نشر (بموافقة حيّة إلزامية)→تأكيد نصي+بصري، لمواصفة ميزة واحدة أو دفعة مواصفات مستقلة على teacher/student/master-admin (أو أي تطبيق GAS).
---

# /gas-pipeline — أنبوب تنفيذ ميزات end-to-end واعٍ بحدّ النسخ ونشر مُراقَب

يبني على `/ship` (راجعه أولاً) ويضيف: تنفيذاً كاملاً من مواصفة (spec) بدل تغيير جاهز، **دمجاً تلقائياً**
بعد اجتياز المراجعة (استثناء موثَّق لهذا الأنبوب تحديداً — العادة العامة في المشروع أن الدمج يدوي)،
و**فحصاً استباقياً لحدّ 200 نسخة** قبل محاولة النشر لا بعد فشلها.

## يُستخدم لكل مواصفة (spec) على حدة

1. **تحديد النطاق عبر `/scope-lock`:** أي تطبيق(ات) GAS تمسّه المواصفة (`teacher`/`student`/
   `master-admin`/…)، وأي ملفات. اعرض عقد النطاق (داخل/خارج + قيود التنفيذ) وتوقّف بانتظار موافقة
   بكلمة واحدة قبل أي تعديل — لا تخمّن، ولا تبدأ الخطوة 2 قبل الموافقة الصريحة.
2. **فرع مخصّص** (`feature/<وصف-قصير>`) — لا تعديل مباشر على `main`.
3. **تنفيذ (implement):** التزم ES5 صارم، اصطلاحات `_`/`*Protected`، عزل `_setActiveTenant` عند
   الحاجة (راجع `<app>/CLAUDE.md` الخاص بالتطبيق المتأثّر لخصوصياته).
4. **البوّابة (gate):**
   ```bash
   npm run gate
   ```
   تعريفها الحيّ في `package.json` — لا تُعدِّد أوامرها هنا ولا تُشغّل بعضها يدوياً.
   + فحص كتل `<script>` لأي HTML ضخم عُدِّل + `node --check` لأي `.js` مستقل.
5. **مراجعة:** شغّل وكيل `gas-reviewer` على الملفات المتغيّرة. أي ملاحظة حاسمة (critical) تُصلَح
   قبل المتابعة؛ لا تتجاهلها لتسريع الأنبوب.
6. **فتح PR** بوصف يذكر المواصفة + نتيجة البوّابة + نتيجة المراجعة.
7. **دمج تلقائي** بعد اجتياز الخطوتين 4 و5 بلا ملاحظات حاسمة معلَّقة — **هذا استثناء لهذا الأنبوب
   فقط** بموافقة صريحة من المالك لكل تشغيلة؛ لا يُطبَّق كعادة عامة على بقية العمل في هذا المستودع
   (راجع `ship` حيث الدمج يبقى يدوياً).

## عند إصلاح خلل (bugfix) تحديداً — اختبار فاشل أولاً، ثم حلقة حتى النجاح

لا تنتقل مباشرة لكتابة الإصلاح. الترتيب الإلزامي لكل bugfix ضمن هذا الأنبوب:

1. **اكتب اختباراً يُعيد إنتاج الخلل ويفشل فعلاً أولاً** — تحقّق بتشغيله أنه يفشل قبل أي تعديل على
   الكود (اختبار لا يفشل بداية لا يثبت شيئاً). المكان المناسب حسب طبيعة الخلل:
   - خلل في ثبات/مصدر بيانات (كخلل قاسم الحضور) → كتلة جديدة في `_build/test-regression-guards.js`
     (`npm run guards`) — تأكيد نصّي على المصدر.
   - خلل في منطق offline/sync → كتلة جديدة في `_build/test-offline.js` (`npm test`).
   - خلل في عرض مرئي (كغلاف الأخبار) → تحقّق DOM عبر chrome-devtools MCP يوثَّق في
     `_docs/regression-baseline/` (راجع نموذج `news-cover-sample-feed.png`)، بالإضافة لتأكيد نصّي
     على القالب إن أمكن.
2. **نفّذ الإصلاح.**
3. **حلقة تكرار حتى تمرّ كل الاختبارات ذات الصلة** (`npm run guards && npm test`، وأي تحقّق بصري
   يدوي إن انطبق) — لا تخرج من الحلقة عند أول فشل جزئي، ولا تُبلغ نجاحاً قبل مرور الاختبار الجديد
   تحديداً (لا يكفي أن تمرّ بقية الاختبارات القديمة).
4. **الاختبار الجديد يبقى في المستودع دائماً** بعد نجاح الإصلاح — هو حارس التراجع لهذا الخلل تحديداً
   مستقبلاً، لا أداة تشخيص مؤقّتة تُحذف.
5. تابع للبوّابة العامة (الخطوة 4 أعلاه) ثم بقية الأنبوب كالمعتاد.

## قبل أي `clasp deploy` — إلزامي، بلا استثناء

8. **فحص حدّ النسخ الاستباقي** (لا تنتظر فشل `clasp deploy`):
   ```bash
   cd <app> && clasp versions 2>&1 | grep -cE "^[0-9]+ -"
   ```
   إن كانت النتيجة **≥ 190** (أي ضمن 10 من الحدّ 200): **لا تحاول النشر إطلاقاً.** أبلغ المالك
   بالعدد الدقيق وأن الحلّ الوحيد يدوي (حذف نسخ قديمة من محرّر Apps Script
   `script.google.com/home/projects/<scriptId>/edit` لهذا المشروع تحديداً) — لا يوجد أمر
   clasp/API لحذف نسخة، فلا "تنظيف تلقائي" ممكن مهما كانت الأتمتة.
9. **بوّابة تغيّر oauthScopes (إن انطبقت):** إن غيّرت المواصفة `oauthScopes` في أي
   `appsscript.json`، طبّق قسم "بوّابة تغيّر oauthScopes" في `/ship` **قبل** الخطوة 10 — أبلغ
   المالك بالنطاقات المتغيّرة، واطلب تأكيد إعادة تفويض حيّ + اختباراً حيّاً فعلياً لميزة تستهلك
   النطاق تحديداً (لا مجرد تحميل صفحة)، ولا تُبلغ نجاحاً قبل اجتيازهما معاً. هذا تكرّر 3 مرات
   موثَّقة (`teacher/CLAUDE.md` بند 4) لأن النشر وحده لا يُعيد تفويض المالك عند تغيّر مجموعة
   النطاقات، والعطل لا يظهر إلا عند أول استخدام لاحق للنطاق المتأثّر.
10. **توقّف لموافقة حيّة** — بصرف النظر عن أي إذن عام سبق منحه لهذا الأنبوب، النشر الفعلي
   (`clasp deploy`) لكل مواصفة يحتاج تأكيداً صريحاً من المالك في حينه (قرار موثَّق: نشر حيّ = 🔴
   أحمر دائماً). اعرض: التطبيق، الملفات المتغيّرة، رابط الـPR المدموج، ونتيجة فحص حدّ النسخ، ثم
   انتظر الموافقة قبل الخطوة التالية.
11. **عند الموافقة — نشر:**
    ```bash
    cd <app> && clasp push -f && clasp deploy --deploymentId <ID الثابت> -d "<وصف مختصر بالمواصفة>"
    ```
12. **تأكيد حيّ نصّي:** اجلب الصفحة/الدالة المتأثّرة عبر وسيط الـWorker (لا رابط GAS مباشر بلا
    كاش) وابحث عن الدليل النصّي على أن الميزة حيّة.
13. **تأكيد حيّ بصري:** عبر أدوات chrome-devtools MCP — `navigate_page` إلى الصفحة الحيّة عبر
    الوسيط، ثم `take_screenshot`. إن كانت الميزة منطقاً خادمياً بحتاً بلا أثر مرئي، وثّق ذلك صراحةً
    بدل التقاط لقطة لا تثبت شيئاً.
14. **إرفاق النتيجة:** أضف تعليقاً على الـPR (المدموج فعلاً) يتضمّن رابط اللقطة/وصفها ونتيجة
    التأكيد النصّي ورقم النسخة الحيّة الجديدة (`@NNN`).
15. **تقرير صادق:** لكل مواصفة — نجحت/فشلت/أُوقفت عند أي خطوة، ولماذا. لا تُبلغ نجاحاً لمواصفة
    أُوقفت عند فحص حدّ النسخ أو عند المراجعة.

## تشغيل دفعة مواصفات مستقلة بالتوازي

الخطوات 1-7 (تنفيذ→بوّابة→مراجعة→PR→دمج) مستقلة تماماً بين المواصفات المختلفة — نفّذها بالتوازي
(Agent tool أو Workflow tool حسب الحجم) لتقليل الزمن الكلي. **الخطوات 8-15 (فحص الحدّ→بوّابة
oauthScopes→موافقة حيّة→نشر→تأكيد) تبقى نقطة توقّف إلزامية لكل مواصفة على حدة** — لا يمكن أتمتتها
بالكامل مهما كان حجم الدفعة، لأن الموافقة الحيّة قبل النشر قرار لا يُفوَّض مسبقاً.
