تخطَّ إلى المحتوى

كيف يعمل التطبيق

الوعد الذي لا يمكنك التحقق منه ليس سوى دعاية. إن القيم التي نلتزم بها لا قيمة لها إلا لأن آلة تحفظها نيابةً عنا — تلقائيًا، وعلى الملأ — حتى لا يضطر الأشخاص الذين يعتمدون على ما تبنيه أبدًا إلى تصديق كلام أحد، بمن فيهم نحن. المحرك هو واجهة سطر أوامر مكتوبة بـ TypeScript (enforcement/cli.ts) تعمل ضمن CI عند كل pull request، وأسبوعيًا على الكتالوج بأكمله، فاحصةً ثلاث طبقات مستقلة — يمكن لشيء أن يختبئ من واحدة، لكن ليس من الثلاث جميعًا.

  • الفحص الأول

    نقرأ الملصق

    نقرأ قائمة المكوّنات الخاصة بكل أداة، ونؤشّر على أي شيء مملوك لبوّاب نستبعده.

    In plain terms ما تعلنه صراحةً.

  • الفحص الثاني

    نتتبّع السلسلة كاملةً

    نتابع سلسلة التوريد بأكملها — ما تعتمد عليه أداتك، وما تعتمد عليه تلك — ونُظهر المسار الدقيق إلى أي شيء مستبعَد.

    In plain terms ما تسحبه في صمت.

  • الفحص الثالث

    نفحص ما تتصل به

    نمسح الشيفرة بحثًا عن اتصالات خفية — استيرادات وعناوين وإعدادات — تتصل سرًّا بمزوّد مستبعَد.

    In plain terms ما تتحدث إليه فعليًا.

أخفِق في أي فحص واحد، ولن تُدرَج.

يعمل الفاحص دون اتصال ويعيد الإجابة نفسها في كل مرة — وهو مفتوح المصدر، فيستطيع أي أحد قراءة القواعد وتشغيله بنفسه.

لا تحذيرات. لا استثناءات. لا تجاوز.

الطبقة 1 — التبعيات المباشرة

Section titled “الطبقة 1 — التبعيات المباشرة”

تقرأ الطبقة 1 بيانات المشروع التعريفية — package.json وCargo.toml وpyproject.toml/requirements.txt وgo.mod وmix.exs وpubspec.yaml وGemfile وملفات بناء Gradle — وتؤشّر على أي تبعية مُعلَنة مباشرةً مملوكة لمنظمة مستبعَدة. وبالنسبة للكتالوج نفسه، تقرأ أيضًا الـ frontmatter لكل مدخل وتتأكد من أن الأداة التي يصفها ليست حزمة مستبعَدة.

مثال: إضافة openai إلى package.json تُخفِق في الطبقة 1 مع "openai" → openai (npm_package: openai).

الطبقة 2 — الشجرة المتعدّية

Section titled “الطبقة 2 — الشجرة المتعدّية”

الحالة الخطيرة هي التبعية التي لم تخترها: مكتبة تثق بها تسحب في صمت عميلًا مستبعَدًا على بُعد ثلاثة مستويات في الأسفل. تجتاز الطبقة 2 رسم الـ lockfile بالكامل — عبر 13 صيغة (npm، pnpm، yarn الكلاسيكي وBerry، Cargo، uv، Poetry، pip-compile، وحدات Go، Bundler، Hex، pub، Gradle) — وتُبلّغ عن السلسلة بأكملها وصولًا إلى الحزمة المستبعَدة.

مثال: a@1.0.0 → openai@4.0.0 → openai يُظهر بالضبط كيف دخلت الحزمة المستبعَدة.

الطبقة 3 — سلاسل المزوّد في الشيفرة المصدرية

Section titled “الطبقة 3 — سلاسل المزوّد في الشيفرة المصدرية”

الملكية ليست القصة كاملة: فالمكتبة المُرخَّصة برخصة متساهلة والمملوكة ملكية مستقلة قد تظل تتضمّن شيفرة تستدعي مزوّدًا مستبعَدًا. تمسح الطبقة 3 الشيفرة المصدرية بحثًا عن ثلاثة أنواع من الإشارات:

  1. الاستيرادات — import OpenAI from "openai"، from facebook_business …، use async_openai:: — أقوى إشارة، والأصعب تبريرًا.

  2. نقاط النهاية — api.openai.com، api.x.ai، graph.facebook.com.

  3. مفاتيح الإعداد — OPENAI_API_KEY، XAI_API_KEY، META_APP_ID.

يمكن أن تظهر نقاط النهاية ومفاتيح الإعداد في سياقات سلبية («نحن لا نستدعي عمدًا api.openai.com»)، لذا تُبلّغ الطبقة 3 عن كل تطابق مع file:line لمراجعة بشرية، وتمنح الاستيرادات أعلى وزن. تعيش تعريفات الإشارات في enforcement/excluded-provider-signals.yaml.

إحكام الأدوات القابلة للضبط: الوصفات

Section titled “إحكام الأدوات القابلة للضبط: الوصفات”

الأداة التي هي نفسها قابلة للضبط للوصول إلى مزوّد مستبعَد لا يجوز قبولها إلا بموجب وصفة إحكام المزوّد — ويجب أن تُثبت الوصفة أن المزوّدين المستبعَدين محظورون، لا مجرد متاحين. هذا تطبيق للاستبعاد، لا إعفاء منه. تتحقق الطبقة 3 من كل وصفة في مقابل عقد:

  • يجب أن تستهدف مدخل كتالوج موسومًا بـ provider_agnostic: true (أي أن الأداة لديها منتقي مزوّد قابل للضبط)؛
  • يجب أن يظهر كل مزوّد نماذج لغة كبيرة (LLM) مستبعَد (OpenAI، xAI) في قائمة must_not_be_one_of الخاصة بالوصفة — وإلا فإن الوصفة لا تحظرهم فعليًا وتُرفَض؛
  • لا يجوز أن يكون أي مزوّد «مسموح به» هو نفسه منظمة مستبعَدة؛
  • يجب أن تحجب خطوات التحقق نقاط نهاية المزوّدين المستبعَدين.

الوصفة التي تنسى حظر OpenAI تُخفِق في البناء. راجع وصفة إحكام Shakespeare لمثال ناجح.

المُحفِّزما الذي يعمل
كل pull requestالطبقة 1 (الكتالوج) + التحقق من الوصفات + astro check + فحص الروابط الميتة
مهمة cron أسبوعية (أيام الإثنين)الطبقات الثلاث جميعًا + license-watcher + maintenance-checker، مع فتح طلبات سحب عند أي انحراف
محليًا، في أي وقتnpm run enforce أو enforcement/cli.ts all --tree .

للمحرك مجموعة اختبارات خاصة به (أكثر من 40 اختبارًا تغطي كل مُحلِّل وعقد الوصفة)، لأن الشيء الذي يُطبّق المساءلة يجب أن يكون خاضعًا للمساءلة هو الآخر.