Elevare Digital मधील तुमचा AI agent निष्क्रिय (idle) झाला कारण नव्याने जोडलेल्या PostgreSQL row-level security (RLS) पॉलिसीमुळे प्रत्येक जॉब रो (job row) फिल्टर झाला, ज्यामुळे क्यू (queue) रिकामी असल्याचे भासले. जोपर्यंत जॉब्सचा ढीग साचला नाही, तोपर्यंत ही चूक लक्षात आली नाही, ज्यामुळे टीमला ऑर्केस्ट्रेटर (orchestrator) रिकामी क्यू कशी ओळखते, याचे डिझाइन पुन्हा तयार करण्यास भाग पाडले.

लपलेला ब्लाइंड स्पॉट

ARIA, ही Elevare ची स्वायत्त (autonomous) AI प्रणाली, प्रलंबित जॉब्ससाठी (pending jobs) PostgreSQL टेबल तपासते (polls). क्वेरी यशस्वी झाली, शून्य रो (rows) परत आले आणि एजंट निष्क्रिय झाला. प्रत्यक्षात टेबल पूर्ण भरलेले होते. एका RLS पॉलिसीने SELECT ॲक्सेस विशिष्ट वापरकर्त्यांच्या संचापुरता मर्यादित केला होता. ऑर्केस्ट्रेटरने अशा 'सर्व्हिस रोल' (service role) द्वारे कनेक्शन केले ज्यामध्ये 'bypass privilege' नव्हता, त्यामुळे डेटाबेसने रिझल्ट सेटमधून प्रत्येक रो शांतपणे काढून टाकले. PostgreSQL फिल्टर केलेल्या रीडला (read) रिकाम्या टेबलप्रमाणेच मानतो, त्यामुळे कोणताही एरर (error), वॉर्निंग (warning) किंवा फेल्युअर कोड दिसला नाही. निष्क्रिय एजंटकडून येणाऱ्या नियमित 'heartbeat' मुळे काहीही चुकीचे घडत आहे, याचा कोणताही संकेत मिळाला नाही.

RLS ने भरलेली क्यू शांततेत कशी बदलली

SELECT दरम्यान RLS प्रत्येक रो ला एक 'predicate' जोडते. जर predicate चुकीचे (false) असेल, तर तो रो रिझल्टमधून गायब होतो. क्लायंटला फक्त पॉलिसी पूर्ण करणारे रो दिसतात; रो लपवले गेले आहेत हे त्याला कधीच समजत नाही. क्यू वर्करसाठी (queue worker), रिकामी रिझल्ट सेट ही खरोखरच रिकामी क्यू असल्यासारखीच दिसते. ऑर्केस्ट्रेटरने “no rows = no work” (रो नाहीत = काम नाही) असे गृहीत धरले आणि पडद्यामागे जॉब्स साचत असतानाच तो त्याच्या 'idle loop' मध्ये गेला.

टीमला असे आढळले की, वाचण्याचे अधिकार (reads) वैयक्तिक वापरकर्त्यांपुरते मर्यादित करण्यासाठी बनवलेली पॉलिसी चुकून 'सर्व्हिस रोल'ला देखील लागू झाली होती. त्या रोलमध्ये विशेष “bypass RLS” अट्रिब्युट नसल्यामुळे, ऑर्केस्ट्रेटरने दिलेल्या प्रत्येक क्वेरीला ही पॉलिसी लागू झाली. हे 'security-vs-observability' (सुरक्षा विरुद्ध निरीक्षणक्षमता) मधील एक क्लासिक ट्रेड-ऑफ (trade-off) दर्शवते: RLS अनधिकृत वापरकर्त्यांपासून डेटाचे संरक्षण करते, परंतु दृश्यमानतेवर (visibility) अवलंबून असलेल्या सिस्टम घटकांसाठी (system components) उपयुक्त असलेला 'फेल्युअर सिग्नल' देखील काढून टाकते.

कॅनरी-चेक पॅटर्न

शांत रिकाम्या रिझल्टवर अवलंबून राहणे थांबवण्यासाठी, Elevare ने “canary” चेक जोडला. नवीन प्रवाह (flow) असा आहे:

  1. प्रलंबित-जॉब्स (pending-jobs) टेबल क्वेरी करा.
  2. जर रो परत आले, तर पूर्वीप्रमाणेच त्यावर प्रक्रिया करा.
  3. जर रिझल्ट रिकामा असेल, तर नेहमी अस्तित्वात असणाऱ्या एका समर्पित 'canary row' विरुद्ध दुसरी क्वेरी करा.
  4. जर कॅनरी क्वेरी अपेक्षित रो परत करत असेल, तर क्यू खरोखरच रिकामी आहे; 'idle heartbeat' लॉग करा.
  5. जर कॅनरी क्वेरी देखील काहीही परत करत नसेल, तर एजंटला काहीच दिसत नाहीये (blind); त्वरित अलर्ट (alert) जारी करा.

आता ऑर्केस्ट्रेटर तीन स्थितींमधील फरक ओळखू शकतो:

  • Jobs found – सामान्य प्रक्रिया.
  • No jobs, canary OK – खरोखरचा रिकाम्या कालावधीचा काळ (idle period).
  • No jobs, canary failed – लपलेला RLS ब्लॉक, अलर्ट ट्रिगर करा.

कॅनरी टेबल हा एक सिंगल रो आहे जो कधीही बदलत नाही. ते सेट करण्यासाठी साधारण एक तास लागला, परंतु यामुळे 'silent failures' चा एक संपूर्ण प्रकार नष्ट झाला.

टीम्सनी काय करावे

जर तुम्ही PostgreSQL किंवा त्यावर आधारित होस्टेड सर्व्हिस (जसे की Supabase) वापरून क्यू वर्कर्स चालवत असाल, तर या स्टेप्स फॉलो करा:

  • “bypass RLS” फ्लॅगसह service-role credential वापरा. यामुळे युजर-लेव्हल पॉलिसी काहीही असली तरी सिस्टम घटक सर्व रो पाहू शकतात.
  • सर्व्हिस रोल्ससाठी 'bypass permissions' उपलब्ध आहेत की नाही हे तपासण्यासाठी RLS पॉलिसी ऑडिट करा. एंड युजर्ससाठी योग्य वाटणारी पॉलिसी चुकून अंतर्गत सेवांना (internal services) अडवू शकते.
  • एक कॅनरी टेबल जोडा (किंवा नेहमी उपलब्ध असलेला एखादा रो वापरा) आणि वर्करच्या 'idle logic' मध्ये कॅनरी चेक समाविष्ट करा. ही अतिरिक्त क्वेरी स्वस्त आहे आणि एक स्पष्ट सेफ्टी नेट (safety net) प्रदान करते.

ट्रेड-ऑफ

सूक्ष्म डेटा ॲक्सेस (fine-grained data access) लागू करण्यासाठी RLS हे एक शक्तिशाली साधन आहे. ते चुकून होणारी डेटा लीक रोखते आणि संपूर्ण कोडबेसमध्ये ॲप्लिकेशन-लेव्हल फिल्टर्स न पसरवता मल्टी-टेनंट आर्किटेक्चरला (multi-tenant architectures) सपोर्ट करते. याचा तोटा असा आहे की, जे घटक "no rows" सिग्नलचा अर्थ "काहीही करायचे नाही" असा समजतात, त्यांच्यापासून ते फेल्युअर लपवू शकते. कॅनरी पॅटर्न RLS ला कमकुवत करत नाही; तो एक हलका (lightweight) व्हेरिफिकेशन स्टेप जोडतो जो निरीक्षणक्षमता (observability) पुन्हा मिळवून देतो.

निष्कर्ष

एक लपलेली RLS पॉलिसी व्यस्त क्यूला शांत डेड एंडमध्ये (dead end) बदलू शकते, ज्यामुळे काम साचत असतानाही AI एजंट्स निष्क्रिय राहतात. सर्व्हिस रोल्सना योग्य 'bypass privilege' द्या आणि प्रत्येक रिकाम्या क्यूच्या रीडला कॅनरी चेकसोबत जोडा; यामुळे टीम्स त्यांचे स्वायत्त वर्कर्स अचूक ठेवू शकतात आणि महागडे ब्लाइंड स्पॉट्स टाळू शकतात.