Code Auditor

وكيل LangGraph يعامل المستودع بوصفه مدخلًا معاديًا

يأخذ Code Auditor رابط Git أو مجلدًا محليًّا ويفترض فيه الأسوأ. يفحصه بحثًا عن البرمجيات الخبيثة والأسرار المسربة قبل أن يلمس الشيفرة أي شيء آخر، ثم يرسم خريطتها ويحللها دون أن يشغلها على الجهاز المضيف أبدًا، ويبني خارطة طريق مرتبة بحسب المخاطر، ثم يصلح بندًا واحدًا في كل مرة داخل بيئة معزولة (sandbox). وكل تغيير ينتظر موافقة إنسان عليه.

النوع
مشروع شخصي، 2026، من تصميمي وتنفيذي بالكامل
الوكيل
آلة حالات LangGraph، 11 عقدة، نقاط حفظ في SQLite
العزل
حاويات Docker مقطوعة عن الشبكة، بحدود قصوى للذاكرة والمعالج وعدد العمليات
النماذج
نموذج Claude Sonnet لخارطة الطريق وللإصلاحات، وكلتاهما بمخرجات منظمة
الاختبارات
478 دالة اختبار للواجهة الخلفية، و18 اختبارًا للواجهة الأمامية

نسخة أولية. كل مرحلة مختبرة ببدائل وهمية للنموذج وللحاويات، وأدوات الفحص مختبرة بالأدوات الحقيقية. أما حلقة الإصلاح فلم تشغل بعد من أولها إلى آخرها مع نموذج حقيقي داخل Docker.

من المستودع إلى خارطة الطريق

النصف الأول من التشغيل يقرأ المستودع ولا ينفذه أبدًا. كل مرحلة عقدة في آلة حالات ثابتة مبنية بـ LangGraph، لا في حلقة وكيل حرة، فلا سبيل إلى إقناع النموذج بتجاوز ترتيب الفحوص.

مستودع واحد عبر مراحل التدقيق
المستودع رابط Git أو مجلد الفحص المسبق برمجيات خبيثة وأسرار الحجر إيقاف التشغيل التقرير سبب التوقف الاستكشاف خريطة ast بلا استيراد التشخيص ruff, mypy, radon التدقيق الأمني bandit, semgrep, osv بوابة الموافقة ملاحظات حرجة التخطيط خارطة مرتبة بالمخاطر خارطة الطريق بنود بحسب الأولوية المستودع رابط Git أو مجلد الفحص المسبق برمجيات خبيثة وأسرار الحجر إيقاف التشغيل التقرير سبب التوقف الاستكشاف خريطة ast بلا استيراد التشخيص ruff, mypy, radon التدقيق الأمني bandit, semgrep, osv بوابة الموافقة ملاحظات حرجة التخطيط خارطة مرتبة بالمخاطر خارطة الطريق بنود بحسب الأولوية
  • إدخال أو إخراج
  • استدعاء LLM
  • شيفرة
  • فحص أو بوابة
  1. المستودع رابط Git ينسخ (clone) بكامل سجله إلى مساحة عمل مؤقتة (المهلة 600 ثانية). أما المجلد المحلي فينسخ دون تتبع الروابط الرمزية.
  2. الفحص المسبق تعمل ClamAV وقواعد YARA و TruffleHog في حاوية مقطوعة عن الشبكة. والبوابة تغلق عند أي خلل (fail closed)، وتعتد بما رصدته أدوات الفحص فعلًا لا بإشارة «passed» التي تعلنها الأداة نفسها. وهنا: لم يرصد شيء.
  3. الاستكشاف يرسم خريطة الوحدات ومخطط الاعتماديات ونقاط الدخول والاختبارات بتحليل الشيفرة عبر ast. لا شيء يستورد ولا ينفذ. الحدود القصوى: 2 ميغابايت للملف و20,000 ملف.
  4. التشخيص تعمل ruff و mypy و radon في حاوية بذاكرة 4 غيغابايت ومقطوعة عن الشبكة؛ وكل ملاحظة تعود مصحوبة بدرجة خطورة.
  5. التدقيق الأمني أدوات bandit و semgrep و osv-scanner و gitleaks، مع تقدير الخطورة وفق CVSS. الدرجة «حرجة» (Critical) محصورة في أدوات الأمن؛ وأي ملاحظة حرجة توقف المسار هنا بانتظار إنسان.
  6. التخطيط يجري اختصار الملاحظات (150 منها تسرد واحدة واحدة والباقي يجمع في فئات) ويعيد Claude Sonnet خارطة طريق ببنية محددة الأنواع. ثم تعيد شيفرة النظام اشتقاق كل درجة خطورة بدل الوثوق بالنموذج.
  7. خارطة الطريق بنود لكل منها درجة خطورة وأولوية ومبرر والملفات التي يمسها، جاهزة لحلقة الإصلاح. وفي غياب النموذج، أو عند خطأ منه، تبنى بدلًا منها خارطة طريق بقواعد ثابتة.

مسارات أخرى في المخطط

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

حلقة الإصلاح، وفيها إنسان

النصف الثاني يغير الشيفرة، بندًا واحدًا من خارطة الطريق في كل مرة. النموذج يكتب الملفات؛ وشيفرة النظام تقرر هل كتابتها آمنة، والبيئة المعزولة تقرر هل تعمل، والإنسان يقرر هل تبقى.

بند واحد من خارطة الطريق عبر حلقة الإصلاح
بند من الخارطة التالي في الأولوية التنفيذ يعيد ملفات كاملة التحقق pytest، للقراءة فقط موافقة بشرية قبول أو رفض التراجع لقطات مطابقة بالبايت التقرير Markdown بلا نموذج بند من الخارطة التالي في الأولوية التنفيذ يعيد ملفات كاملة التحقق pytest، للقراءة فقط موافقة بشرية قبول أو رفض التراجع لقطات مطابقة بالبايت التقرير Markdown بلا نموذج
  • إدخال أو إخراج
  • استدعاء LLM
  • شيفرة
  • فحص أو بوابة
  1. بند من الخارطة البند الأعلى أولوية. يجري التحقق من النطاق ومن سقف التكلفة البالغ 10 دولارات قبل أي استدعاء للنموذج.
  2. التنفيذ يرسل إلى النموذج ما لا يزيد على 4 ملفات كاملة، فيعيد ملفات جديدة كاملة، لا فروقًا (diffs) ولا أوامر shell. كل ملف يجري التحقق منه، ثم تؤخذ له لقطة، ثم يكتب كتابة ذرية؛ أما الفرق فيحسبه difflib.
  3. التحقق يعمل pytest في بيئة معزولة مقطوعة عن الشبكة، ومساحة العمل مربوطة فيها للقراءة فقط. يفشل أحد الاختبارات.
  4. التنفيذ محاولة ثانية. لكل بند 3 محاولات في المجموع، بما فيها الأولى.
  5. التحقق تنجح الاختبارات. والحالة «تعذر التحقق» تبقى مفصولة عن «فشل»، ولا تعاد محاولتها أبدًا.
  6. موافقة بشرية يتوقف المخطط مؤقتًا عبر interrupt()‎ إلى أن يوافق المراجع أو يرفض. ويجب أن يسجل القرار أيضًا صفًّا في قاعدة البيانات، والصف هو المرجع.
  7. التقرير بعد آخر بند، تقرير Markdown تولده شيفرة النظام لا النموذج. و«تم الإصلاح» تعني: نال الموافقة، وجرى التحقق منه، ولم يتراجع عنه.

مسارات أخرى في المخطط

  • استمرار الفشل بعد 3 محاولات، أو بلوغ الحد الأقصى للتكرارات: تراجع مطابق بايتًا ببايت، ثم البوابة.
  • رفض دون تعليق: يلغى التغيير. رفض مع تعليق: عودة إلى التنفيذ برصيد محاولات جديد.
  • لم يكتب شيء على القرص: تترك البوابة التشغيل يواصل دون توقف.

الاحتواء

المستودع غير موثوق، ومخرجات النموذج كذلك. وكلاهما مقيد بإحكام.

  • أربعة أنواع من الحاويات

    الفحص المسبق (2 غيغابايت)، والتحليل (4 غيغابايت)، والأمن (6 غيغابايت)، وبيئة الاختبارات المعزولة (2 غيغابايت)، وكلها مقطوعة عن الشبكة، بمعالجين و512 عملية ومهلة بين 10 دقائق و30 دقيقة.

  • الكتابة على المضيف، والتشغيل داخل الصندوق

    التعديلات تكتب في مساحة العمل على الجهاز المضيف؛ أما الشيفرة فلا تشغل إلا داخل البيئة المعزولة، على مجلد مربوط للقراءة فقط. واللقطات تحفظ خارج هذا المجلد.

  • حدود صارمة لكل تشغيل

    50 تكرارًا، وساعة واحدة من الزمن الفعلي، وسقف تكلفة قدره 10 دولارات يفحص قبل كل استدعاء للنموذج، وحد عودية (recursion limit) في LangGraph يساوي 200.

  • أدوات مثبتة الإصدارات

    ruff 0.9.10, mypy 1.15.0, radon 6.0.1, bandit 1.8.6, semgrep 1.172.0, gitleaks 8.24.0, osv-scanner 2.4.0, TruffleHog 3.88.0, pytest 8.3.4

ما كشفه مستودع حقيقي

في مذكرات المشروع توثيق لأول تشغيل يدوي على مستودع حقيقي من 56 ملفًّا، دون Docker ودون نموذج. من أصل 137 ملاحظة أمنية، كانت 134 منها القاعدة B101 في bandit، أي مجرد عبارة assert، ولم يقع أي من بنود خارطة الطريق الـ 17 ضمن قائمة السماح الافتراضية لأداة الإصلاح.

الضجيج والنطاق، لا جودة النموذج، هما ما يجب أن تتقنه أداة كهذه أولًا.

خيارات هندسية

  • آلة حالات، لا وكيل حر

    عقد ثابتة لكل منها مهمة ضيقة. النموذج يخطط ويكتب الملفات؛ ولا يختار أبدًا الفحص الذي يجري بعده.

  • الإغلاق عند الفشل

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

  • درجة الخطورة تحددها الشيفرة

    للنموذج أن يقترح درجة خطورة؛ لكن شيفرة النظام تعيد اشتقاقها من مصدر الملاحظة. والدرجة «حرجة» لأدوات الأمن وحدها.

  • ملفات كاملة، لا رقع

    النموذج يعيد ملفات كاملة. والفروق يحسبها difflib، والمخرجات غير الآمنة ترفض قبل كتابة أي شيء.

  • الموافقة تحتاج إلى سجل

    يوقف interrupt في LangGraph التشغيل مؤقتًا، والاستئناف يشترط وجود صف موافقة في قاعدة البيانات. لا صف، لا استئناف.

  • تقرير بلا نموذج

    التقرير النهائي تولده شيفرة النظام من الأحداث المسجلة، فلا يمكنه أن يبالغ فيما أُصلح.

التقنيات

الوكيل
LangGraph، نقاط حفظ SQLite، Anthropic SDK (مخرجات منظمة)
التحليل
ruff، mypy، radon، bandit، semgrep، osv-scanner، gitleaks
الفحص المسبق
ClamAV، YARA، TruffleHog
الواجهة الخلفية
Python 3.12، FastAPI، WebSockets، SQLModel، Alembic، Docker SDK
الواجهة الأمامية
React 19، TypeScript، Vite، Tailwind CSS 4
الجودة
pytest، Vitest، اختبارات للمحللات على مخرجات حقيقية ملتقطة من الأدوات

هل تبني شيئًا مشابهًا؟

يسعدني أن أشرح التصميم والمفاضلات، أو ما سأغيّره في الخطوة التالية.