Skip to main content

title: البنية المعمارية description: “كيفية عمل معالج الخطاف وتحميل الإعدادات وتقييم السياسات بشكل داخلي” icon: sitemap

تشرح هذه الوثيقة كيفية عمل failproofai داخليًا: كيف يعترض نظام الخطاف استدعاءات أدوات الوكيل، وكيف يتم تحميل الإعدادات ودمجها، وكيف يتم تقييم السياسات، وكيف تراقب لوحة المعلومات نشاط الوكيل.

نظرة عامة

يحتوي failproofai على نظامين فرعيين مستقلين:
  1. معالج الخطاف - عملية CLI سريعة يستدعيها Claude Code على كل استدعاء لأداة وكيل. يقيّم السياسات ويعيد قرارًا.
  2. مراقب الوكيل (لوحة المعلومات) - تطبيق ويب Next.js لمراقبة جلسات الوكيل وإدارة السياسات.
يشارك كلا النظامين الفرعيين ملفات الإعدادات في ~/.failproofai/ ودليل المشروع .failproofai/، لكنهما يعملان كعمليات منفصلة ولا يتواصلان إلا عبر نظام الملفات.

معالج الخطاف

التكامل مع Claude Code

عند تشغيل failproofai policies --install، يكتب إدخالات مثل هذه في ~/.claude/settings.json:
ثم يستدعي Claude Code failproofai --hook PreToolUse كعملية فرعية قبل كل استدعاء أداة، ويمرر حمولة JSON على stdin.

تنسيق الحمولة

بالنسبة لأحداث PostToolUse، تحتوي الحمولة أيضًا على tool_result بمخرجات الأداة. يفرض المعالج حد أقصى بحجم 1 ميجابايت على stdin. يتم تجاهل الحمولات التي تتجاوز هذا الحد وتسمح جميع السياسات ضمنيًا.

تنسيق الاستجابة

رفض (PreToolUse):
رفض (PostToolUse):
تعليمات (أي حدث ما عدا Stop):
حدث التعليمات الخاص:
  • رمز الخروج: 2
  • السبب المكتوب على stderr (وليس stdout)
السماح:
  • رمز الخروج: 0
  • stdout فارغ
السماح مع رسالة: يسمح allow(message) لسياسة بإرسال سياق معلومات مرة أخرى إلى Claude حتى عند السماح بالعملية. يكتب معالج الخطاف JSON التالي إلى stdout (وليس ملف إعدادات — هذه هي استجابة المعالج لـ Claude Code، تمامًا مثل استجابات الرفض والتعليمات أعلاه):
  • رمز الخروج: 0 (العملية مسموح بها)
  • عند إرجاع عدة سياسات allow مع رسالة، يتم دمج رسائلها مع فواصل أسطر في سلسلة additionalContext واحدة
  • إذا لم توفر أي سياسة رسالة، يكون stdout فارغًا (كما هو الحال من قبل)

خط أنابيب المعالجة

تنفذ src/hooks/handler.ts خط الأنابيب الكامل:
تعمل العملية بأكملها في أقل من 100 ميلي ثانية للحمولات النموذجية بدون استدعاءات LLM.

تحميل الإعدادات

تنفذ src/hooks/hooks-config.ts تحميل الإعدادات ثلاثي النطاق.
منطق الدمج:
  • enabledPolicies - اتحاد مخصص عبر جميع الملفات الثلاثة
  • policyParams - لكل سياسة، الملف الأول الذي يحددها يفوز بالكامل
  • customPoliciesPath - الملف الأول الذي يحددها يفوز
  • llm - الملف الأول الذي يحددها يفوز
تستخدم لوحة معلومات الويب readHooksConfig() (عام فقط) للقراءة والكتابة، حيث لا يتم استدعاؤها مع cwd مشروع.

تقييم السياسة

تشغيل src/hooks/policy-evaluator.ts السياسات بالترتيب. لكل سياسة:
  1. ابحث عن مخطط params الخاص بالسياسة (إن وجد).
  2. اقرأ policyParams[policy.name] من الإعدادات المدمجة.
  3. دمج القيم المتوفرة من المستخدم فوق الافتراضيات الخاصة بالمخطط لإنتاج ctx.params.
  4. استدعِ policy.fn(ctx) مع السياق المحل.
  5. إذا كانت النتيجة deny، توقف فورًا وأعد هذا القرار.
  6. إذا كانت النتيجة instruct، جمّع الرسالة وتابع.
  7. إذا كانت النتيجة allow، انتقل إلى السياسة التالية.
بعد تشغيل جميع السياسات:
  • إذا تم إرجاع أي deny، صدر استجابة الرفض.
  • إذا تم جمع أي استجابات instruct، أصدر استجابة تعليمات واحدة مع دمج جميع الرسائل.
  • بخلاف ذلك، أصدر استجابة سماح (stdout فارغ، الخروج 0).

السياسات المدمجة

تحدد src/hooks/builtin-policies.ts جميع 39 سياسة مدمجة كائنات BuiltinPolicyDefinition:
تصرح السياسات التي تقبل params بـ PolicyParamsSchema مع الأنواع والقيم الافتراضية لكل معامل. يدرج محيّم السياسة القيم المحلولة في ctx.params قبل استدعاء fn. تقرأ دوال السياسة ctx.params دون حماية فارغة لأن الافتراضيات يتم تطبيقها دائمًا أولاً. يستخدم تطابق النمط داخل السياسات رموز الأوامر المحللة (argv)، وليس مطابقة السلسلة الخام. هذا يمنع الالتفاف عبر حقن مشغلات shell (على سبيل المثال، نمط لـ sudo systemctl status * لا يمكن التفافه عن طريق إضافة ; rm -rf / إلى الأمر).

السياسات المخصصة

تنفذ src/hooks/custom-hooks-registry.ts سجل مدعوم بـ globalThis:
يحمل src/hooks/custom-hooks-loader.ts ملف السياسة الخاص بالمستخدم:
  1. اقرأ customPoliciesPath من الإعدادات؛ تخطَّ إذا كان غائبًا.
  2. حل إلى مسار مطلق؛ تحقق من وجود الملف.
  3. أعد كتابة جميع استيرادات from "failproofai" إلى مسار dist الفعلي بحيث يتم حل customPolicies إلى سجل globalThis نفسه.
  4. أعد كتابة الاستيرادات المحلية الانتقالية بشكل متكرر لضمان التوافق مع ESM.
  5. اكتب ملفات .mjs مؤقتة وimport() ملف الإدخال.
  6. استدعِ getCustomHooks() لاسترجاع الخطافات المسجلة.
  7. نظف جميع الملفات المؤقتة في كتلة finally.
عند أي خطأ (ملف غير موجود، خطأ بناء جملة، فشل استيراد)، يتم تسجيل الخطأ إلى ~/.failproofai/hook.log ويعيد المحمل مصفوفة فارغة. السياسات المدمجة لم تتأثر. يتم تقييم السياسات المخصصة بعد جميع السياسات المدمجة. لا يزال deny السياسة المخصصة يختصر السياسات المخصصة الإضافية (لكن جميع المدمجة قد عملت بالفعل في هذه المرحلة).

تسجيل النشاط

بعد كل حدث خطاف، يضيف المعالج سطر JSONL إلى ~/.failproofai/hook-activity.jsonl:
سطر واحد لكل سياسة اتخذت قرارًا بعدم السماح. لا يتم تسجيل قرارات السماح (للحفاظ على حجم الملف صغيرًا).

بنية لوحة المعلومات

لوحة المعلومات عبارة عن تطبيق Next.js 16 يستخدم App Router مع React Server Components و Server Actions.
تدفق البيانات:
  • تستدعي مكونات الصفحة lib/projects.ts وlib/log-entries.ts لقراءة بيانات المشروع/الجلسة مباشرة من نظام الملفات (لا توجد طبقة API للقراءات).
  • تستخدم صفحة السياسات Server Actions لجميع التغييرات (تبديل، تحديث المعاملات، التثبيت/الإزالة).
  • يحلل عارض الجلسة تنسيق نصوص JSONL الخاص بـ Claude ويرسم خط زمني للرسائل واستدعاءات الأدوات.
قرارات التصميم الرئيسية:
  • لا قاعدة بيانات - جميع الحالات الدائمة موجودة في ملفات عادية (~/.failproofai/, ~/.claude/projects/).
  • Server Actions للتغييرات - لا توجد حاجة إلى REST API لعمليات CRUD.
  • React Server Components لصفحات القراءة - تحميل أسرع للبداية، لا توجد حزمة عميل لجلب البيانات.
  • مكونات العميل فقط حيث تكون التفاعلية مطلوبة (تبديلات السياسة، البحث عن النشاط، عارض السجل).

تخطيط الملفات