دخل وكيل الذكاء الاصطناعي الخاص بك في Elevare Digital في حالة خمول لأن سياسة أمن مستوى الصف (RLS) التي تمت إضافتها حديثاً في PostgreSQL قامت بتصفية كل صف من صفوف المهام، مما جعل الطابور يبدو فارغاً. لم يُلاحظ الخطأ حتى تراكمت المهام، مما أجبر الفريق على إعادة تصميم كيفية اكتشاف المنسق (orchestrator) للطابور الفارغ.
النقطة العمياء الخفية
ARIA، نظام الذكاء الاصطناعي المستقل في Elevare، يقوم بفحص جدول PostgreSQL بحثاً عن المهام المعلقة. نجح الاستعلام، وأعاد صفر صفوف، فدخل الوكيل في حالة خمول. في الواقع، كان الجدول ممتلئاً. قامت سياسة RLS بتقييد الوصول عبر SELECT لمجموعة محددة من المستخدمين. اتصل المنسق بدور خدمة (service role) يفتقر إلى صلاحية التجاوز (bypass privilege)، لذا قامت قاعدة البيانات بصمت بحذف كل صف من مجموعة النتائج. تعامل PostgreSQL مع القراءة المفلترة بنفس طريقة التعامل مع الجدول الفارغ، لذا لم يظهر أي خطأ أو تحذير أو رمز فشل. ولم تعطِ نبضات القلب (heartbeat) السليمة من الوكيل الخامل أي إشارة إلى وجود خطأ ما.
كيف حولت RLS طابوراً ممتلئاً إلى صمت
تضيف RLS شرطاً (predicate) إلى كل صف أثناء عملية SELECT. إذا كان الشرط خاطئاً، يختفي الصف من النتيجة. يرى العميل فقط الصفوف التي تستوفي السياسة؛ ولا يعرف أبداً أن الصفوف قد تم إخفاؤها. بالنسبة لعامل الطابور، تبدو مجموعة النتائج الفارغة تماماً مثل طابور فارغ حقاً. افترض المنسق أن "لا توجد صفوف = لا يوجد عمل" ودخل في حلقة الخمول بينما كانت المهام تتراكم خلف الكواليس.
اكتشف الفريق أن السياسة التي كانت تهدف إلى حصر القراءات للمستخدمين الأفراد قد شملت عن غير قصد دور الخدمة نفسه. ولأن الدور يفتقر إلى سمة "تجاوز RLS" الخاصة، فقد طُبقت السياسة على كل استعلام أصدره المنسق. يوضح هذا المقايضة الكلاسيكية بين الأمن وقابلية المراقبة (observability): تحمي RLS البيانات من المستخدمين غير المصرح لهم، ولكنها تحجب أيضاً إشارة فشل مفيدة لمكونات النظام التي تعتمد على الرؤية والوضوح.
نمط فحص الكناري (canary-check)
لكسر الاعتماد على النتيجة الفارغة الصامتة، أضافت Elevare فحص "الكناري" (canary check). التدفق الجديد هو:
- استعلام عن جدول المهام المعلقة.
- إذا تمت إعادة صفوف، فقم بمعالجتها كما في السابق.
- إذا كانت النتيجة فارغة، قم بإصدار استعلام ثانٍ مقابل صف كناري مخصص يجب أن يكون موجوداً دائماً.
- إذا أعاد استعلام الكناري الصف المتوقع، فإن الطابور فارغ حقاً؛ قم بتسجيل نبضة خمول (idle heartbeat).
- إذا لم يعيد استعلام الكناري أي شيء أيضاً، فإن الوكيل "أعمى"؛ قم بإطلاق تنبيه فوري.
الآن يميز المنسق بين ثلاث حالات:
- تم العثور على مهام – معالجة عادية.
- لا توجد مهام، الكناري سليم – فترة خمول حقيقية.
- لا توجد مهام، فشل الكناري – حظر RLS مخفي، تفعيل التنبيه.
جدول الكناري هو صف واحد لا يتغير أبداً. استغرق إعداده حوالي ساعة واحدة، لكنه يقضي على فئة كاملة من حالات الفشل الصامتة.
ما يجب على الفرق فعله
إذا كنت تقوم بتشغيل عمال الطابور مقابل PostgreSQL أو خدمة مستضافة مبنية عليها (مثل Supabase)، فاتبع هذه الخطوات:
- استخدم بيانات اعتماد دور الخدمة (service-role credential) مع علامة "تجاوز RLS". يتيح ذلك لمكونات النظام رؤية جميع الصفوف بغض النظر عن سياسات مستوى المستخدم.
- دقق في سياسات RLS بحثاً عن أذونات التجاوز المفقودة لأدوار الخدمة. السياسة التي تبدو صحيحة للمستخدمين النهائيين قد تحاصر الخدمات الداخلية عن غير قصد.
- أضف جدول كناري (أو صفاً مكافئاً موجوداً دائماً) وادمج فحص الكناري في منطق الخمول الخاص بالعامل. الاستعلام الإضافي غير مكلف ويوفر شبكة أمان واضحة.
المقايضة
تظل RLS أداة قوية لفرض الوصول الدقيق للبيانات. فهي تمنع تسرب البيانات العرضي وتدعم بنيات تعدد المستأجرين (multi-tenant architectures) دون نشر فلاتر على مستوى التطبيق في جميع أنحاء الكود المصدري. الجانب السلبي هو أنها قد تخفي حالات الفشل عن المكونات التي تتوقع أن تعني إشارة "لا توجد صفوف" البسيطة "لا يوجد شيء للقيام به". نمط الكناري لا يضعف RLS؛ بل يضيف خطوة تحقق خفيفة الوزن تستعيد قابلية المراقبة.
الخلاصة
يمكن لسياسة RLS مخفية أن تحول طابوراً مزدحماً إلى طريق مسدود صامت، مما يترك وكلاء الذكاء الاصطناعي في حالة خمول بينما تتراكم الأعمال. امنح أدوار الخدمة صلاحية التجاوز المناسبة واقترن كل عملية قراءة لطابور فارغ بفحص الكناري؛ وبذلك يمكن للفرق الحفاظ على دقة عمل عمالهم المستقلين وتجنب النقاط العمياء المكلفة.
