8 मिनट पढ़ें

क्या race में approval queue का call order बना रहता है?

Approval queue call order तय करता है कि दो agent writes एक साथ आने पर human approval का अर्थ बना रहता है या नहीं। Race को दोहराएँ और cards, execution व journals की जाँच करें।

क्या race में approval queue का call order बना रहता है?

मानवीय approval का अर्थ बहुत कम रह जाता है अगर बाद वाला agent call पहले वाले से आगे निकल जाए, सिर्फ इसलिए कि उसका card पहले click हो गया। जब दो writes एक ही remote state के लिए प्रतिस्पर्धा कर रहे हों, तो gateway को किसी व्यक्ति के दोनों cards छूने से पहले उनका क्रम तय करना चाहिए। फिर dispatch के दौरान और audit record में भी वही क्रम सुरक्षित रहना चाहिए।

इसे नज़रअंदाज़ करना आसान है, क्योंकि सामान्य स्थिति में एक card, एक click और एक सफल response होता है। समस्या तब दिखती है जब दो agent processes एक ही क्षण में requests भेजते हैं, reviewer दिखाई दे रहे cards को असुविधाजनक क्रम में approve करता है और target वही request स्वीकार करता है जो पहले पहुँचती है। मैंने teams को इसे concurrency कहते देखा है। यह बस ऐसा undefined decision है जो उस समय लिया गया जब इंसान को लगा था कि नियंत्रण उसके हाथ में है।

Order gateway के call स्वीकार करते ही शुरू होता है

Call order वह क्रम है जिसमें action gateway एक ही conflicting resource के लिए requests को किसी lane में स्वीकार करता है। यह cards के render होने का क्रम, किसी व्यक्ति के click करने का क्रम, network connection खुलने का क्रम या remote responses लौटने का क्रम नहीं है।

हर accepted call को 42, 43 और 44 जैसे immutable ticket दें। Ticket को request description, calling process identity, target और lane identifier के साथ store करें। Approval माँगने से पहले ticket मौजूद होना चाहिए। वरना interface केवल यह बता पाएगा कि reviewer ने कौन सा request पहले देखा था। Race को फिर से समझने के लिए इतना पर्याप्त नहीं है।

Lane वह scope है जिसमें order बदलने से result बदल सकता है। एक ही deployment environment को overwrite करने वाले दो requests एक lane में होने चाहिए। एक ही remote incident record में append करने वाले दो calls भी एक lane में होने चाहिए। Package metadata fetch करने वाले request और किसी अलग test service को update करने वाले request को शायद एक-दूसरे का इंतज़ार न करना पड़े। हर action को global order देना सुरक्षित लगता है, लेकिन इससे कोई unrelated slow request हर agent के लिए outage बन जाता है।

मुश्किल हिस्सा lane को ईमानदारी से चुनना है। केवल target hostname अक्सर बहुत व्यापक होता है। केवल endpoint path अक्सर बहुत संकीर्ण होता है। PATCH /documents/7 और POST /documents/7/publish एक ही document को प्रभावित करते हैं, भले उनके paths अलग हों। अगर gateway के पास यह संबंध निकालने के लिए पर्याप्त जानकारी नहीं है, तो उन actions को एक ही configured lane में रखें। ऐसा न मानें कि remote service उस ordering promise को पूरा कर देगी जो gateway ने कभी दिया ही नहीं।

Admission record का रूप लगभग ऐसा होना चाहिए:

ticket=42 lane=release-prod event=accepted action=write-release caller=agent-a
ticket=43 lane=release-prod event=accepted action=write-release caller=agent-b

बाद में ये lines एक सटीक सवाल का जवाब देती हैं: gateway ने पहले किस call की जिम्मेदारी ली? वे यह दावा नहीं करतीं कि ticket 42 पहले पूरा हुआ। Slow target की वजह से permitted execution model के अनुसार ticket 43 पहले या बाद में finish हो सकता है। Gateway को इस model को स्पष्ट करना चाहिए, न कि journal को बाद में अपनी तरफ से कोई model गढ़ने देना चाहिए।

Approval decision है, आगे निकलने की अनुमति नहीं

अगर reviewer request A से पहले request B पर decision लेता है, तो इससे B पहले वाला request नहीं बन जाता। इसका केवल इतना मतलब है कि B ने एक शर्त पूरी कर ली है और अब अपनी बारी का इंतज़ार कर रहा है।

यह अंतर इसलिए धुंधला पड़ जाता है क्योंकि approval interfaces आमतौर पर हर card को एक अलग prompt की तरह दिखाते हैं। जिस action का order पर कोई असर नहीं है, उसके लिए यह ठीक है। Competing writes में यह तरीका विफल होता है। अगर interface दोनों cards को actionable रहने देता है, तो B पर click करने से B को सीधे dispatcher के पास नहीं जाना चाहिए। B को approved waiting state में जाना चाहिए। Dispatcher lane के head ticket को check करे और केवल सबसे पुराने ऐसे ticket को dispatch करे जिसे allow decision मिल चुका हो।

Head ticket के लिए gateway के तीन उचित outcomes हैं:

  • Approval उस ticket को dispatch करने की अनुमति देता है।
  • Rejection terminal refusal दर्ज करता है, फिर अगले ticket को release करता है।
  • Expiry या explicit cancellation terminal outcome दर्ज करता है, फिर अगले ticket को release करता है।

एक चौथा व्यवहार समस्या पैदा करता है: बाद वाला approval तुरंत dispatch हो जाता है क्योंकि उससे पहले वाले request पर अभी decision नहीं हुआ। यह सुविधाजनक लगता है, क्योंकि reviewer को जल्दी result मिल जाता है। लेकिन इससे remote sequence user interface के timing पर निर्भर हो जाता है। कोई व्यक्ति A के parameters देखने के लिए उसे खोल सकता है और B को harmless housekeeping call समझकर approve कर सकता है। तब system B को पहले भेज देता है, जबकि pair को queue की तरह दिखाया गया था।

User interface को state स्पष्ट रूप से दिखानी चाहिए। Head card पर Approve और Reject दिए जा सकते हैं। बाद वाले cards पर decision लिया जा सकता है, लेकिन उनका status बताए कि वे ticket 42 के पीछे इंतज़ार कर रहे हैं। दूसरा तरीका यह है कि पहले वाले tickets resolve होने तक उनके controls रोक दिए जाएँ। दोनों तरीके order सुरक्षित रख सकते हैं। पहले तरीके से reviewer को अधिक control मिलता है, दूसरा समझने में आसान है। Interface को कभी यह संकेत नहीं देना चाहिए कि हर positive click से तुरंत execution शुरू हो जाता है।

Sallyport के per session authorization और per call approval controls request boundary को स्पष्ट करते हैं, लेकिन approval decision से पहले order के लिए ticket फिर भी assign होना चाहिए। अगर product केवल cards का एक असंगठित समूह record करता है, तो reviewer queue का सही मूल्यांकन नहीं कर सकता।

ऐसे writes से race को दोहराएँ जो trace छोड़ते हों

एक उपयोगी test दो स्वतंत्र agent processes को एक write lane की ओर भेजता है और target से arrival order record करवाता है। दो reads, दो idempotent status checks या अलग-अलग records को update करने वाले दो requests का इस्तेमाल न करें। ऐसे tests पास हो सकते हैं, जबकि queue overtaking की अनुमति दे रही हो।

ऐसा disposable HTTP endpoint इस्तेमाल करें जो POST body स्वीकार करे और मिले हुए ticket को file या database table में append करे। उसे received ticket वापस करना चाहिए। अगर यह drill केवल local test address पर चल रही है, तो target को authentication की जरूरत नहीं है। उद्देश्य gateway के approval और dispatch path को test करना है, credential injection को नहीं।

यह छोटा Node server एक साधारण arrival log बनाता है:

const fs = require("node:fs");
const http = require("node:http");

http.createServer((request, response) => {
  let body = "";
  request.on("data", chunk => { body += chunk; });
  request.on("end", () => {
    const item = JSON.parse(body);
    fs.appendFileSync("arrival.log", `${item.ticket} ${item.value}\n`);
    response.writeHead(200, { "content-type": "application/json" });
    response.end(JSON.stringify({ received: item.ticket }));
  });
}).listen(8787);

एक approved action configure करें जो उस endpoint को POST /write भेजे और अपने JSON body में request ticket रखे। एक process से दो calls serially करवाने के बजाय दो नए agent processes शुरू करें। दोनों processes एक ही action को अलग values के साथ submit करें, जैसे A और B। दोनों calls को approval की जरूरत होनी चाहिए, ताकि cards साथ में pending रहें।

शुरुआत में मिलने वाला evidence साधारण और स्पष्ट होना चाहिए:

Sessions
42 accepted agent-a write A
43 accepted agent-b write B

Approval cards
42 write A
43 write B

arrival.log
(empty)

अगर cards ticket order के उलटे दिखाई दें, तो वहीं रुककर जाँच करें। उलटा visual order गलत execution का प्रमाण नहीं है, लेकिन इससे reviewer को एक गलत कहानी के आधार पर action लेने का मौका मिलता है। अगर एक समय में केवल एक card दिखाई दे, तो record करें कि क्या दूसरे request को पहले ही ticket मिल चुका है और क्या journal बताता है कि वह पहले request के पीछे इंतज़ार कर रहा है। दूसरे card को छिपाना ठीक है। उसका अस्तित्व छिपाना ठीक नहीं है।

इस drill को कई बार चलाएँ। पहले A और फिर B शुरू करें। फिर पहले B और उसके बाद A शुरू करें। उन्हें test harness की अनुमति के अनुसार जितना संभव हो उतने करीब शुरू करें। एक process के gateway में प्रवेश करने के बाद थोड़ी delay जोड़ें, ताकि scheduling कम accidental रहे। बार-बार overlap जरूरी है, क्योंकि एक सफल run अक्सर enforced rule के बजाय सुविधाजनक thread schedule का परिणाम होता है।

Card order, dispatch order और completion order अलग होते हैं

Test को तीन orders collect करने चाहिए, क्योंकि वे अलग सवालों के जवाब देते हैं और उन्हें एक ही column में नहीं मिलाना चाहिए।

Card order वह क्रम है जिसमें reviewer pending decisions देख सकता है। किसी application के cards अलग-अलग event loop turns में draw होने पर भी, एक lane के भीतर यह ticket order का पालन करना चाहिए। Card arrival timestamp दिखा सकता है, लेकिन निर्णायक field ticket है।

Execution order वह क्रम है जिसमें gateway accepted actions को HTTP या SSH channel के लिए release करता है। Strictly serialized write lane में target को ticket 42, ticket 43 से पहले दिखना चाहिए। Gateway को request channel को सौंपने से ठीक पहले dispatched event emit करना चाहिए। Dispatch का अनुमान response event से न लगाएँ। Target write प्राप्त करके state बदल सकता है और response भेजने से पहले connection खो सकता है।

Completion order वह क्रम है जिसमें responses, timeouts या transport errors लौटते हैं। अलग lanes में overlapping calls की अनुमति हो तो यह dispatch order से अलग हो सकता है। एक ही lane में भी asynchronous implementation completion को देर से record कर सकती है, क्योंकि वह network cleanup के बाद logs flush करती है। Completion order उपयोगी operational information है, लेकिन उसे causal order को overwrite नहीं करना चाहिए।

एक छोटा test record इस अंतर को स्पष्ट रखता है:

42 accepted
43 accepted
42 card-shown
43 card-shown
43 approved
42 approved
42 dispatched
42 succeeded
43 dispatched
43 succeeded

इस run में 43 approved का 42 approved से पहले दिखाई देना अपेक्षित है। Contract यह है कि 42 dispatched, 43 dispatched से पहले दिखाई दे। अगर application केवल final successes log करती है, तो दोनों बातें गायब हो जाती हैं और investigator यह नहीं बता सकता कि user ने B को पहले approve किया था, dispatcher A से आगे निकल गया था, या target ने पहले से released दो requests को फिर से क्रमबद्ध किया था।

RFC 9110 safe HTTP methods और state changes का अनुरोध करने वाले methods के बीच अंतर बताता है। यहाँ यह अंतर महत्वपूर्ण है: gateway observations के लिए ढीला order स्वीकार कर सकता है, जबकि writes के लिए स्पष्ट concurrency contract चाहिए। RFC 9110 दो स्वतंत्र client connections के बीच उपयोगी total order नहीं देता। Approval को call से पहले रखने के बाद यह decision gateway की जिम्मेदारी है।

दूसरे card को पहले approve करके रोकें

Agent run देखें
Sessions agent runs को अलग-अलग journal में दर्ज करता है, इसलिए किसी run को revoke करने पर उसका इतिहास नहीं खोता।

सबसे मजबूत बुनियादी race test जानबूझकर B को पहले approve करता है। इससे पता चलता है कि implementation approval को state transition मानती है या direct send button।

Tickets 42 और 43 को एक ही lane में pending रखकर शुरू करें। Ticket 43 को approve करें। Card या journal को approved, waiting for 42 जैसी state में बदलना चाहिए। Target का arrival.log खाली रहना चाहिए। फिर ticket 42 को approve करें। Target को पहले 42 A और उसके बाद 43 B मिलना चाहिए, और activity record में दोनों dispatch इसी क्रम में दिखने चाहिए।

अब यही test ticket 42 को reject करके दोहराएँ। Target log में केवल B होना चाहिए। Journal में फिर भी दोनों tickets होने चाहिए:

42 accepted
43 accepted
43 approved
42 rejected reason=user
43 dispatched
43 succeeded

Rejection एक action outcome है, action की अनुपस्थिति नहीं। अगर journal इसे छोड़ देता है, तो बाद में log देखने वाले व्यक्ति को B के execute होने का कारण नहीं मिलेगा, जबकि पहले वाला request गायब है। इससे गलत निष्कर्ष निकल सकते हैं: शायद attacker ने approval bypass किया, शायद app ने data खो दिया, या शायद reviewer ने ऐसी चीज approve की जो उसे दिखाई ही नहीं दी।

इसके बाद timeout test करें। B के पहले से approved रहते हुए A का approval expire होने दें। Application को A की expiry एक बार record करनी चाहिए, B को eligible बनाना चाहिए और B को dispatch करना चाहिए। उसे expired और rejected दोनों नहीं बनाना चाहिए, क्योंकि background timer और देर से आए click में race हो सकती है। Ticket state पर atomic compare and swap के साथ एक terminal decision चुनें। हारने वाले event को देखना चाहिए कि ticket पहले ही resolve हो चुका है और कुछ नहीं करना चाहिए।

अंत में A के resolve होने से पहले approved B को cancel करें। B कभी dispatch नहीं होना चाहिए। उसकी terminal state cancelled होनी चाहिए, और बाद में A को resolve करने पर B फिर active नहीं होना चाहिए। इससे queue की एक आम bug पकड़ी जाती है: dispatcher approved tickets की पुरानी list रखता है और cancellation handler के उसे visible queue से हटाने के बाद भी उस entry को भेज देता है।

अच्छा test हर result को अलग-अलग assert करता है। केवल यह assert करके संतुष्ट न हों कि target को अपेक्षित final state मिली। गलत sequence के बाद भी final state सही दिख सकती है, अगर B ने A को overwrite कर दिया हो, retries ने duplicate छिपा दिया हो या target ने अपना conflict rule लागू किया हो।

Retries और slow targets के बीच ticket सुरक्षित रखें

Channel request को retry करे, तब भी उसका स्थान queue में बना रहना चाहिए। Connection failure के बाद नया ticket बनाना approval का अर्थ बदल देता है और बाद वाले request को उससे आगे निकलने दे सकता है।

मान लें ticket 42 dispatch होता है, gateway को response मिलने से पहले TCP connection बंद हो जाता है और target ने write लागू किया है या नहीं, यह पता नहीं है। Ticket 43 इंतज़ार करता है। Gateway के पास कई policies हो सकती हैं: unknown outcome report करके रुकना, target support करे तो idempotency token के साथ retry करना, या नए human decision की मांग करना। उसे 42 को चुपचाप हटाकर 43 को ऐसे भेजने की अनुमति नहीं है जैसे 42 कभी मौजूद ही नहीं था।

सही policy remote operation पर निर्भर करती है। Idempotency identifier स्वीकार करने वाला endpoint original ticket का इस्तेमाल करके retry को पर्याप्त रूप से सुरक्षित बना सकता है। Blind SSH command ऐसा नहीं कर सकती। उस स्थिति में 42 के लिए unknown result report करें, lane को blocked रखें या human intervention के बाद उसे स्पष्ट रूप से abandon करें और कारण दर्ज करें। 43 को अपने आप release करने से नुकसान बढ़ सकता है, अगर 43 यह मानकर चल रहा हो कि 42 विफल हुआ है।

इसे ऐसे target के साथ test करें जो A प्राप्त करे, अपना arrival record लिखे और HTTP exchange पूरा होने से पहले response connection बंद कर दे। Gateway को ऐसा trace सुरक्षित रखना चाहिए:

42 accepted
42 approved
42 dispatched attempt=1
42 outcome=unknown
43 accepted
43 approved waiting-for=42

Ticket 43 अंततः चलेगा या नहीं, यह documented operational choice होनी चाहिए। अस्वीकार्य व्यवहार यह है कि journal gateway के पास evidence आने से पहले 42 को failed बताए और फिर उस दावे पर निर्भर B को सफलतापूर्वक चला दे।

Slow requests एक अलग implementation error दिखाते हैं। Remote response का इंतज़ार करते समय mutex पकड़े रखने वाला dispatcher हर चीज को गलती से serialize कर सकता है, unrelated lanes और user interface work को भी। जो dispatcher अपनी order state बहुत जल्दी release कर देता है, वह अगले ticket को race में आगे निकलने देता है। Lane की admission और dispatch state छोटी रखें, dispatch event persist करें, request channel को सौंपें और फिर result का इंतज़ार करें। Strict serialization लागू होने पर उसी lane के दूसरे ticket को आगे न निकलने दें।

Audit journal को causality सुरक्षित रखनी चाहिए

Action gateway को लॉक रखें
Vault lock होने पर हर action रोक दिया जाता है। macOS पर Secure Enclave और Touch ID का इस्तेमाल होता है।

Hash-chained audit record यह साबित करता है कि सुरक्षित रखे गए records में चुपचाप बदलाव नहीं हुआ। इससे अपने आप confusing event sequence समझ में नहीं आती। Concurrent approval race समझाने के लिए event model में पर्याप्त जानकारी फिर भी चाहिए।

Card दिखाई देने से पहले acceptance event record करें। Ticket और actor या interaction method के साथ approval decision record करें। HTTP request या SSH command के channel में जाने से पहले dispatch record करें। Terminal channel outcome को किसी पुराने event की जगह न लिखें। हर event को wall time के अलावा अपना append position भी चाहिए।

Wall clocks debugging में उपयोगी हैं, लेकिन अकेले order तय नहीं कर सकतीं। दो events का timestamp समान resolution वाला हो सकता है, clocks बदल सकती हैं और application अलग threads से writes को queue कर सकती है। Append position या sequence number यह order स्थापित करता है कि journal ने हर event को किस क्रम में स्वीकार किया। Per request ticket lane में intended order स्थापित करता है। दोनों सुरक्षित रखें।

दो-write drill में इन facts की तुलना करें:

  • Acceptance positions 42 को 43 से पहले दिखाती हैं।
  • Approval events 43 को 42 से पहले दिखा सकते हैं।
  • जब दोनों calls सफल हों, तो dispatch positions 42 को 43 से पहले दिखाती हैं।
  • Target arrival file 42 को 43 से पहले दिखाती है।
  • Terminal outcomes उन्हीं tickets से जुड़े रहते हैं, उनकी जगह नहीं लेते।

Sallyport Sessions और Activity views को एक encrypted hash-chained audit log से बनाता है, और sp audit verify ciphertext पर offline उस chain की जाँच कर सकता है। इसलिए event selection खास तौर पर महत्वपूर्ण है: verification बता सकता है कि records बदले नहीं गए, जबकि ticket और event types इंसान को बताते हैं कि वास्तव में क्या हुआ।

Visible journal को completion time के अनुसार sort करके उसे history न कहें। इससे network race decision sequence जैसी दिखाई देती है। Primary timeline को durable append position के अनुसार sort करें, फिर उसके साथ ticket number और timestamps दिखाएँ। किसी एक agent process का filtered view भी original positions सुरक्षित रखे, ताकि reviewer देख सके कि दो events के बीच कोई दूसरा request इंतज़ार कर रहा था, बिना अनुमान लगाए।

FIFO conflicting effects पर लागू होता है, हर byte पर नहीं

Causality की समीक्षा आसान रखें
एक encrypted, hash-chained audit log Sessions और Activity दोनों का आधार है।

FIFO queue conflicting effects के बारे में एक promise है। यह हर network operation को एक thread से चलाने या unresolved write के पीछे harmless read को रोकने का कारण नहीं है।

हर action को classify करके शुरू करें। Shared environment को बदलने वाली deployment command को lane चाहिए। Billing action बनाने वाले HTTP POST को, संभवतः account के आधार पर, lane चाहिए। Static artifact पढ़ने वाला fetch अक्सर स्वतंत्र रूप से चल सकता है। केवल disk space report करने वाला SSH command observational हो सकता है, लेकिन सावधान रहें: shell startup files, temporary files या remote command wrappers के ज़रिए commands के छिपे effects हो सकते हैं। जब तक effects स्पष्ट न हों, ambiguous commands को writes मानें।

लोकप्रिय विकल्प यह कहना है कि हर approval independent है, क्योंकि reviewer request को देख सकता है। यह आकर्षक है, क्योंकि इससे queue design की जरूरत हट जाती है। लेकिन reviewer हर request को अलग-अलग समझ सकता है और फिर भी यह संकेत न मिले कि B मान रहा है कि A पहले हो चुका है। Human review missing serialization context की भरपाई नहीं करता।

दूसरी गलती single global queue है। इससे order सरल हो जाता है, लेकिन कोई remote host रुकने पर application अटकी हुई लगने लगती है। अलग lanes के स्पष्ट नाम, stable resource selection और उनकी पहचान करने वाले journal fields होने चाहिए। अगर आप यह नहीं समझा सकते कि दो actions एक ही lane में क्यों हैं, तो ordering promise को test भी नहीं कर सकते।

Per call approval को lanes का विकल्प न बनाएं। हर use पर click की जरूरत रखने से इंसान हर action का मूल्यांकन कर सकता है। इससे यह तय नहीं होता कि दो approved actions एक-दूसरे से आगे निकल सकते हैं या नहीं। ये अलग failure modes वाले अलग controls हैं।

Race को release criterion बनाएँ

Queue bug आमतौर पर किसी साफ crash के रूप में नहीं आती। बाद में यह unexplained remote state, गलत action पर लागू लगी approval या ऐसे journal के रूप में सामने आती है जो incident review को स्पष्ट निष्कर्ष तक नहीं पहुँचा पाता। Shared state बदलने वाले हर action type के लिए दो-write drill को release test मानें।

Release criterion को केवल success responses से अधिक जाँचना चाहिए। Overlapping calls बनाएं, approval sequence उलटें, पहले request को reject करें, उसे expire होने दें, दूसरे request को cancel करें और dispatch के बाद जानबूझकर unknown result पैदा करें। हर case में ticket sequence, card states, dispatch events, target arrival log और journal entries save करें।

जब इनमें से कोई record दूसरे से असहमत हो, तो उसे display issue कहने की जल्दी न करें। Display issue पहला दिखाई देने वाला संकेत हो सकता है कि application के अलग हिस्सों ने order की अलग definitions चुन ली हैं। Contract को admission पर ठीक करें, फिर card, dispatcher, target test और journal से वही contract report करवाएँ।

पहला practical action छोटा है: एक conflicting write lane में immutable ticket जोड़ें और test में बाद वाले ticket को पहले approve करें। अगर वह request अपने पहले वाले पड़ोसी से पहले target तक पहुँचती है, तो approval queue अभी उस काम को नियंत्रित नहीं करती जिसे वह approve करने का दावा करती है।

सामान्य प्रश्न

दो concurrent agent calls का क्रम कैसे तय करें?

Gateway के request स्वीकार करते ही, approval card दिखाई देने से पहले एक monotonic ticket दें। केवल timestamp कमजोर प्रमाण है, क्योंकि समान clock values, clock में बदलाव और अलग-अलग processes के कारण क्रम अस्पष्ट हो सकता है।

क्या पहले approved request को पहले execute होना चाहिए?

Approval का क्रम admission order नहीं बदलना चाहिए। अगर request B को request A से पहले approval मिल जाए, तो B को तब तक रोके रखें जब तक A किसी terminal outcome तक न पहुँच जाए, या system किसी अलग serialization contract को स्पष्ट रूप से दर्ज न करे।

जब queue में सबसे पहला write reject हो जाए तो क्या होता है?

पहले वाली rejected request queue में अपनी जगह फिर भी लेती है। उस rejection को दर्ज करें, फिर अगले approved request को आगे बढ़ने दें। Rejected request को history से चुपचाप न मिटाएँ।

क्या timed-out approval बाद के सभी requests को रोक सकता है?

Timeout को rejection की तरह संभालना चाहिए: एक ticket से जुड़ा एक terminal decision। अगला request तभी आगे बढ़े जब timeout record durable हो और journal में दिखाई दे।

क्या सभी agent actions के लिए एक global FIFO queue चाहिए?

Queues को उस resource के आधार पर अलग करें जिसकी state में टकराव हो सकता है। एक ही remote document पर होने वाले दो writes को serialize करना चाहिए, जबकि अलग services के स्वतंत्र calls अलग lanes में चल सकते हैं, बशर्ते journal हर lane का admission order सुरक्षित रखे।

Server logs approval queue से अलग क्यों हो सकते हैं?

Proxy या HTTP server में connections के race के कारण requests gateway से अलग क्रम में पहुँच सकती हैं। Test में gateway tickets की तुलना downstream arrival records से करें। Network arrival को सही scheduling का प्रमाण न मानें।

Concurrent writes को test करने का सुरक्षित तरीका क्या है?

ऐसा write endpoint इस्तेमाल करें जो कोई दिखाई देने वाला, ordered side effect बनाए, जैसे ticket और payload को local file में जोड़ना। GET requests से test करने पर failure छिप जाता है, क्योंकि reads अक्सर reorder होने पर भी ठीक चलते हैं।

क्या journal order को execution या completion order का पालन करना चाहिए?

Activity journal को हर request का causal sequence सुरक्षित रखना चाहिए: accepted, approval decision, dispatched और terminal result। Completion time अलग हो सकता है, लेकिन वह यह क्रम नहीं बदलना चाहिए कि gateway ने request को कब स्वीकार या dispatch किया।

क्या process identity approval auditing के लिए पर्याप्त है?

Signed process identity बताती है कि request किसने किया, जबकि queue ticket बताता है कि competing calls के बीच वह request कहाँ है। बाद में किसी decision का audit करने के लिए दोनों जानकारियाँ चाहिए।

Approval queue regression test में किन cases को शामिल करना चाहिए?

दो-write race को बार-बार चलाएँ और approval timing उलटें। Rejection, timeout, cancellation और जानबूझकर धीमे पहले target को भी शामिल करें। Ticket order, card order, dispatch order और journal causality में कोई भी mismatch उस lane के लिए release blocker होना चाहिए।

Sallyport

Sallyport आपके AI एजेंट के लिए API कॉल और SSH कमांड चलाता है। कुंजियाँ आपके Mac पर एक लोकल वॉल्ट में रहती हैं; आप हर रन को स्वीकृत करते हैं और हर क्रिया एक सीलबंद जर्नल में दर्ज होती है।

© 2026 Sallyport · Apache-2.0 के तहत ओपन सोर्स · Oleg Sotnikov