Elevare Digital ਵਿਖੇ ਤੁਹਾਡਾ AI agent ਇਸ ਲਈ idle ਹੋ ਗਿਆ ਕਿਉਂਕਿ ਇੱਕ ਨਵੀਂ ਜੋੜੀ ਗਈ PostgreSQL row-level security (RLS) policy ਨੇ ਹਰ job row ਨੂੰ filter ਕਰ ਦਿੱਤਾ, ਜਿਸ ਨਾਲ queue ਖਾਲੀ ਦਿਖਾਈ ਦੇਣ ਲੱਗੀ। ਇਹ ਗਲਤੀ ਉਦੋਂ ਤੱਕ ਨਜ਼ਰ ਨਹੀਂ ਆਈ ਜਦੋਂ ਤੱਕ jobs ਦਾ ਢੇਰ ਨਹੀਂ ਲੱਗ ਗਿਆ, ਜਿਸ ਕਾਰਨ team ਨੂੰ orchestrator ਦੁਆਰਾ ਖਾਲੀ queue ਦਾ ਪਤਾ ਲਗਾਉਣ ਦੇ ਤਰੀਕੇ ਨੂੰ ਮੁੜ ਡਿਜ਼ਾਈਨ ਕਰਨ ਲਈ ਮਜਬੂਰ ਹੋਣਾ ਪਿਆ।
ਲੁਕਿਆ ਹੋਇਆ blind spot
ARIA, Elevare ਦਾ autonomous AI system, pending jobs ਲਈ ਇੱਕ PostgreSQL table ਨੂੰ poll ਕਰਦਾ ਹੈ। Query ਸਫਲ ਰਹੀ, ਜ਼ੀਰੋ rows ਵਾਪਸ ਆਈਆਂ, ਅਤੇ agent ਸੌਂ ਗਿਆ। ਅਸਲ ਵਿੱਚ table ਭਰਿਆ ਹੋਇਆ ਸੀ। ਇੱਕ RLS policy ਨੇ SELECT access ਨੂੰ ਉਪਭੋਗਤਾਵਾਂ ਦੇ ਇੱਕ ਖਾਸ ਸਮੂਹ ਤੱਕ ਸੀਮਤ ਕਰ ਦਿੱਤਾ ਸੀ। Orchestrator ਇੱਕ service role ਨਾਲ ਜੁੜਿਆ ਹੋਇਆ ਸੀ ਜਿਸ ਕੋਲ bypass privilege ਦੀ ਕਮੀ ਸੀ, ਇਸ ਲਈ database ਨੇ ਚੁੱਪਚਾਪ result set ਵਿੱਚੋਂ ਹਰ row ਨੂੰ ਹਟਾ ਦਿੱਤਾ। PostgreSQL ਇੱਕ filtered read ਨੂੰ ਖਾਲੀ table ਵਾਂਗ ਹੀ ਮੰਨਦਾ ਹੈ, ਇਸ ਲਈ ਕੋਈ error, warning, ਜਾਂ failure code ਪ੍ਰਗਟ ਨਹੀਂ ਹੋਇਆ। Idle agent ਤੋਂ ਮਿਲਣ ਵਾਲੇ ਇੱਕ ਸਿਹਤਮੰਦ heartbeat ਨੇ ਕੋਈ ਇਸ਼ਾਰਾ ਨਹੀਂ ਦਿੱਤਾ ਕਿ ਕੁਝ ਗਲਤ ਸੀ।
RLS ਨੇ ਇੱਕ ਭਰੀ ਹੋਈ queue ਨੂੰ ਚੁੱਪ ਕਿਵੇਂ ਬਣਾ ਦਿੱਤਾ
RLS ਇੱਕ SELECT ਦੌਰਾਨ ਹਰ row ਵਿੱਚ ਇੱਕ predicate ਜੋੜਦਾ ਹੈ। ਜੇਕਰ predicate false ਹੈ, ਤਾਂ row result ਵਿੱਚੋਂ ਗਾਇਬ ਹੋ ਜਾਂਦੀ ਹੈ। Client ਸਿਰਫ਼ ਉਹਨਾਂ rows ਨੂੰ ਦੇਖਦਾ ਹੈ ਜੋ policy ਨੂੰ ਪੂਰਾ ਕਰਦੇ ਹਨ; ਉਸਨੂੰ ਕਦੇ ਪਤਾ ਨਹੀਂ ਲੱਗਦਾ ਕਿ rows ਲੁਕਾਈਆਂ ਗਈਆਂ ਸਨ। ਇੱਕ queue worker ਲਈ, ਇੱਕ ਖਾਲੀ result set ਬਿਲਕੁਲ ਇੱਕ ਅਸਲ ਖਾਲੀ queue ਵਾਂਗ ਲੱਗਦਾ ਹੈ। Orchestrator ਨੇ ਮੰਨ ਲਿਆ ਕਿ “no rows = no work” ਅਤੇ ਉਹ ਆਪਣੇ idle loop ਵਿੱਚ ਚਲਾ ਗਿਆ ਜਦੋਂ ਕਿ ਪਿੱਛੇ jobs ਇਕੱਠੀਆਂ ਹੁੰਦੀਆਂ ਰਹੀਆਂ।
Team ਨੇ ਪਤਾ ਲਗਾਇਆ ਕਿ ਇੱਕ policy, ਜਿਸਦਾ ਮਕਸਦ reads ਨੂੰ ਵਿਅਕਤੀਗਤ ਉਪਭੋਗਤਾਵਾਂ ਤੱਕ ਸੀਮਤ ਕਰਨਾ ਸੀ, ਨੇ ਅਣਜਾਣੇ ਵਿੱਚ service role ਨੂੰ ਹੀ ਫੜ ਲਿਆ ਸੀ। ਕਿਉਂਕਿ ਉਸ role ਕੋਲ ਵਿਸ਼ੇਸ਼ “bypass RLS” attribute ਨਹੀਂ ਸੀ, ਇਸ ਲਈ policy orchestrator ਦੁਆਰਾ ਜਾਰੀ ਕੀਤੀ ਗਈ ਹਰ query 'ਤੇ ਲਾਗੂ ਹੋ ਗਈ। ਇਹ ਇੱਕ ਕਲਾਸਿਕ security-vs-observability trade-off ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ: RLS ਅਣਅਧਿਕਾਰਤ ਉਪਭੋਗਤਾਵਾਂ ਤੋਂ ਡਾਟਾ ਦੀ ਰੱਖਿਆ ਕਰਦਾ ਹੈ, ਪਰ ਇਹ ਉਹਨਾਂ system components ਲਈ ਇੱਕ ਲਾਭਦਾਇਕ failure signal ਨੂੰ ਵੀ ਹਟਾ ਦਿੰਦਾ ਹੈ ਜੋ visibility 'ਤੇ ਨਿਰਭਰ ਕਰਦੇ ਹਨ।
The canary-check pattern
ਇੱਕ ਚੁੱਪਚਾਪ ਖਾਲੀ result 'ਤੇ ਨਿਰਭਰਤਾ ਨੂੰ ਤੋੜਨ ਲਈ, Elevare ਨੇ ਇੱਕ “canary” check ਜੋੜਿਆ। ਨਵਾਂ flow ਇਹ ਹੈ:
- Pending-jobs table ਨੂੰ query ਕਰੋ।
- ਜੇਕਰ rows ਵਾਪਸ ਆਉਂਦੀਆਂ ਹਨ, ਤਾਂ ਉਹਨਾਂ ਨੂੰ ਪਹਿਲਾਂ ਵਾਂਗ process ਕਰੋ।
- ਜੇਕਰ result ਖਾਲੀ ਹੈ, ਤਾਂ ਇੱਕ ਸਮਰਪਿਤ canary row ਦੇ ਵਿਰੁੱਧ ਦੂਜੀ query ਜਾਰੀ ਕਰੋ ਜੋ ਹਮੇਸ਼ਾ ਮੌਜੂਦ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ।
- ਜੇਕਰ canary query ਉਮੀਦ ਕੀਤੀ ਗਈ row ਵਾਪਸ ਕਰਦੀ ਹੈ, ਤਾਂ queue ਸੱਚਮੁੱਚ ਖਾਲੀ ਹੈ; ਇੱਕ idle heartbeat log ਕਰੋ।
- ਜੇਕਰ canary query ਵੀ ਕੁਝ ਵਾਪਸ ਨਹੀਂ ਕਰਦੀ, ਤਾਂ agent ਅੰਨ੍ਹਾ (blind) ਹੈ; ਤੁਰੰਤ alert ਜਾਰੀ ਕਰੋ।
ਹੁਣ orchestrator ਤਿੰਨ ਸਥਿਤੀਆਂ (states) ਵਿੱਚ ਫਰਕ ਕਰ ਸਕਦਾ ਹੈ:
- Jobs ਮਿਲ ਗਏ – normal processing.
- ਕੋਈ jobs ਨਹੀਂ, canary OK – ਅਸਲ idle ਸਮਾਂ।
- ਕੋਈ jobs ਨਹੀਂ, canary ਫੇਲ ਹੋ ਗਿਆ – ਲੁਕਿਆ ਹੋਇਆ RLS block, alert trigger ਕਰੋ।
Canary table ਇੱਕ ਸਿੰਗਲ row ਹੈ ਜੋ ਕਦੇ ਨਹੀਂ ਬਦਲਦੀ। ਇਸਨੂੰ ਸੈੱਟ ਕਰਨ ਵਿੱਚ ਲਗਭਗ ਇੱਕ ਘੰਟਾ ਲੱਗਿਆ, ਪਰ ਇਹ silent failures ਦੀ ਪੂਰੀ ਸ਼੍ਰੇਣੀ ਨੂੰ ਖਤਮ ਕਰ ਦਿੰਦਾ ਹੈ।
Team ਨੂੰ ਕੀ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ
ਜੇਕਰ ਤੁਸੀਂ PostgreSQL ਜਾਂ ਇਸ 'ਤੇ ਬਣੀ ਕਿਸੇ hosted service (ਜਿਵੇਂ ਕਿ Supabase) ਦੇ ਵਿਰੁੱਧ queue workers ਚਲਾਉਂਦੇ ਹੋ, ਤਾਂ ਇਹਨਾਂ ਕਦਮਾਂ ਦੀ ਪਾਲਣਾ ਕਰੋ:
- “bypass RLS” flag ਵਾਲੇ service-role credential ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ system components ਨੂੰ user-level policies ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ ਸਾਰੀਆਂ rows ਦੇਖਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ।
- Service roles ਲਈ missing bypass permissions ਲਈ RLS policies ਦਾ audit ਕਰੋ। ਇੱਕ policy ਜੋ end users ਲਈ ਸਹੀ ਲੱਗਦੀ ਹੈ, ਉਹ ਅਣਜਾਣੇ ਵਿੱਚ internal services ਨੂੰ ਫਸਾ ਸਕਦੀ ਹੈ।
- ਇੱਕ canary table (ਜਾਂ ਇੱਕ ਸਮਾਨ ਹਮੇਸ਼ਾ ਮੌਜੂਦ row) ਜੋੜੋ ਅਤੇ canary check ਨੂੰ worker ਦੇ idle logic ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ। ਵਾਧੂ query ਸਸਤੀ ਹੈ ਅਤੇ ਇੱਕ ਸਪਸ਼ਟ safety net ਪ੍ਰਦਾਨ ਕਰਦੀ ਹੈ।
The trade-off
RLS fine-grained data access ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ਸਾਧਨ ਬਣਿਆ ਹੋਇਆ ਹੈ। ਇਹ ਅਚਾਨਕ ਡਾਟਾ ਲੀਕ ਹੋਣ ਤੋਂ ਰੋਕਦਾ ਹੈ ਅਤੇ codebase ਵਿੱਚ application-level filters ਖਿਲਾਰਨ ਦੀ ਬਿਨਾਂ multi-tenant architectures ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ। ਇਸਦਾ ਨੁਕਸਾਨ ਇਹ ਹੈ ਕਿ ਇਹ ਉਹਨਾਂ components ਤੋਂ ਅਸਫਲਤਾਵਾਂ ਨੂੰ ਲੁਕਾ ਸਕਦਾ ਹੈ ਜੋ ਇੱਕ ਸਧਾਰਨ “no rows” signal ਦਾ ਮਤਲਬ “ਕੁਝ ਕਰਨ ਲਈ ਨਹੀਂ” ਮੰਨਦੇ ਹਨ। Canary pattern RLS ਨੂੰ ਕਮਜ਼ੋਰ ਨਹੀਂ ਕਰਦਾ; ਇਹ ਇੱਕ ਹਲਕਾ (lightweight) verification step ਜੋੜਦਾ ਹੈ ਜੋ observability ਨੂੰ ਬਹਾਲ ਕਰਦਾ ਹੈ।
Takeaway
ਇੱਕ ਲੁਕੀ ਹੋਈ RLS policy ਇੱਕ ਰੁੱਝੀ ਹੋਈ queue ਨੂੰ ਇੱਕ ਚੁੱਪ dead end ਵਿੱਚ ਬਦਲ ਸਕਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਕੰਮ ਇਕੱਠਾ ਹੁੰਦਾ ਰਹਿੰਦਾ ਹੈ ਅਤੇ AI agents idle ਰਹਿੰਦੇ ਹਨ। Service roles ਨੂੰ ਸਹੀ bypass privilege ਦਿਓ ਅਤੇ ਹਰ empty-queue read ਨੂੰ canary check ਨਾਲ ਜੋੜੋ; teams ਆਪਣੇ autonomous workers ਨੂੰ ਸਹੀ ਰੱਖ ਸਕਦੀਆਂ ਹਨ ਅਤੇ ਮਹਿੰਗੇ blind spots ਤੋਂ ਬਚ ਸਕਦੀਆਂ ਹਨ।
