CLI टूल्स को बैकग्राउंड डेमन डिफ़ॉल्ट में नहीं चलाना चाहिए
AI CLI टूल्स अब डिफ़ॉल्ट रूप से खुद को अपडेट करने वाले बैकग्राउंड डेमन इंस्टॉल कर रहे हैं। यह डेवलपर टूल्स के भरोसे को कैसे तोड़ता है और बेहतर रास्ता क्या है।

एक डेवलपर AI कोडिंग असिस्टेंट आज़माने के लिए npm install -g @openai/codex चलाता है, और उसे एक ऐसा लगातार चलने वाला, खुद को अपडेट करने वाला बैकग्राउंड डेमन मिल जाता है जिसकी उसने कभी मांग नहीं की थी। हाल ही में OpenAI के Codex CLI के यूज़र्स को यही पता चला कि यह टूल एक बैकग्राउंड प्रोसेस अपने-आप शुरू कर देता है, ~/.codex में pid और lock फ़ाइलें लिखता है, पुराने बाइनरी वर्ज़न डिस्क पर रखे रहता है (एक यूज़र ने लगभग 12 GB बताया), और बिना पूछे खुद को अपडेट कर लेता है। यह किसी एक कंपनी की बग की कहानी नहीं है। यह उस भरोसे के मॉडल की कहानी है जिस पर डेवलपर टूलिंग दशकों से टिकी रही है, और यह देखना चिंताजनक है कि इसे कितनी चुपचाप छोड़ा जा रहा है।
मैंने इंफ़्रास्ट्रक्चर और इंसिडेंट रिस्पॉन्स में कई साल बिताए हैं, और यहाँ का पैटर्न मैंने पहले भी देखा है: एडवेयर में, समझौता हुए बिल्ड एजेंट्स में, और हार्डवेयर विक्रेताओं के भेजे गए 'मददगार' अपडेटर सर्विस में। तो चलिए, इस डिज़ाइन के आम बचाव लेते हैं और हर एक को परखते हैं, क्योंकि उनमें से ज़्यादातर प्रोडक्शन एनवायरनमेंट की असली दुनिया में टिकते नहीं।
मिथक 1: “यह बस एक अपडेटर है, ब्राउज़र भी यही करते हैं”
यही सबसे आम बचाव है, और सुनने में वाजिब लगता है। Chrome और Firefox लगातार खुद को अपडेट करते रहते हैं। VS Code और Slack भी ऐसा ही करते हैं। तो CLI हार्नेस को क्यों न करे?
असल बात यह है कि भरोसे का संदर्भ बिल्कुल अलग है। ब्राउज़र एक GUI एप्लिकेशन है, जिसमें पहली बार चलने का अनुभव होता है, दिखने वाला सेटिंग्स पेज होता है, साइन किया हुआ इंस्टॉलर होता है, और सबसे अहम, एक ऐसा अपडेट चैनल होता है जिसे एक दशक से ज़्यादा समय से सख़्त बनाया और ऑडिट किया गया है। Chrome का अपडेटर दुनिया के सबसे ज़्यादा हमले झेलने वाले सॉफ़्टवेयर में से एक है, और Google उसे सुरक्षित रखने के लिए पूरी टीमें लगाता है। Chrome इंस्टॉल करते समय आप अपडेट होने के लिए साफ़ तौर पर सहमत होते हैं।
npm से इंस्टॉल हुए CLI के साथ एक अलग अंतर्निहित समझौता होता है। डेवलपर्स उम्मीद करते हैं कि वह बुलाए जाने पर चले और काम खत्म होने पर रुक जाए। यह उम्मीद केवल पुरानी आदत नहीं है, बल्कि पूरे सिस्टम का आधार है। CI पाइपलाइन, कंटेनर, शेयर्ड बिल्ड सर्वर और सिक्योरिटी रिव्यू, सब मानकर चलते हैं कि npm i -g some-tool से मिली बाइनरी माँग पर ही चलती है। एक बैकग्राउंड डेमन जो लॉगआउट के बाद भी बचा रहे, खुद को दोबारा शुरू करे और अपनी ही बाइनरी बदल दे, इन सारी उम्मीदों को तोड़ देता है। मैं ऐसे इंसिडेंट कॉल्स में रहा हूँ जहाँ 'यह प्रोसेस हमारे हिसाब में क्यों नहीं है?' वाले सवाल ने एक सामान्य अलर्ट को तीन घंटे की फ़ॉरेंसिक जांच में बदल दिया। जब तक साबित न हो जाए, बिना हिसाब वाला लगातार चलने वाला प्रोसेस समझौते से अलग नहीं दिखता।
ब्लास्ट रेडियस में भी व्यावहारिक फ़र्क है। आपका ब्राउज़र वेब पेज एक सैंडबॉक्स में रेंडर करता है। AI कोडिंग हार्नेस शेल कमांड चलाता है, आपके सोर्स ट्री को पढ़ता है, और अक्सर अपने एनवायरनमेंट में API keys और क्लाउड क्रेडेंशियल्स रखता है। ऐसे टूल को एक खुद-बदलने वाला, हमेशा चालू रहने वाला हिस्सा देना ब्राउज़र अपडेट से कहीं बड़ा जोखिम है।
मिथक 2: “यूज़र कॉन्फ़िग फ़्लैग से इसे बंद कर सकते हैं”
तकनीकी रूप से सही है, और व्यवहार में बिल्कुल बेकार। हाँ, एक फ़ीचर फ़्लैग मौजूद है:
# ~/.codex/config.toml
[features]
daemon_auto_start = false
समस्या यह है कि जब यूज़र इसे ढूंढने गए, तब यह डॉक्यूमेंटेड नहीं था। जिस विकल्प के बारे में किसी को पता ही न हो, वह सहमति नहीं है, वह एक जाल है। और देखिए कि समुदाय ने बैकअप योजना क्या बनाई: pid और lock फ़ाइलें हटाना, उन्हें /dev/null पर सिमलिंक करना, और chattr +i से उन्हें immutable करना, ताकि अगर फ़्लैग कभी हट जाए तो डेमन स्टार्टअप पर क्रैश हो जाए। जब यूज़र आपके सॉफ़्टवेयर से बचने के लिए अपनी ही होम डायरेक्टरी में जाल बिछाने लगें, तो आपने कॉन्फ़िगरेशन सिस्टम नहीं बनाया। आपने एक विरोधी रिश्ता बना लिया है।
इस तरह की गतिशीलता पर मैं पहले फ़िटनेस ऐप्स के लोकेशन डेटा लीक के संदर्भ में लिख चुका हूँ: पैटर्न हमेशा एक जैसा होता है। फ़ीचर डिफ़ॉल्ट रूप से चालू होकर आता है, टॉगल छिपा या अनडॉक्यूमेंटेड होता है, और सतर्क रहने का बोझ यूज़र पर आ जाता है। डिफ़ॉल्ट ही नीति होते हैं। जो डिफ़ॉल्ट लगातार चलने वाला प्रोसेस इंस्टॉल करता है, वह बताता है कि सॉफ़्टवेयर असल में किसकी सेवा कर रहा है।
हल बेहद आसान है और हमेशा से था: पहली बार चलाने पर एक बार पूछें। Codex runs a background service to keep itself updated. Enable it? [y/N]। apt, Homebrew और ज़्यादातर Linux डेमन दशकों से स्पष्ट सहमति पर चलते आए हैं। systemctl enable इसीलिए बना है, क्योंकि बूट पर कुछ शुरू करना एक सोचा-समझा कदम होना चाहिए।
मिथक 3: “तेज़ चलने के लिए चुपचाप सेल्फ-अपडेट ज़रूरी है”
इसमें कुछ दम है, और मैं इसे पूरी ईमानदारी से परखना चाहता हूँ। AI हार्नेस सच में तेज़ी से बदलते हैं। तीन हफ़्ते पुराना CLI बदले हुए API के साथ गड़बड़ कर सकता है, और बग वाला क्लाइंट जो बाहर चल रहा हो, वह सपोर्ट का बड़ा बोझ है। एक लीगल-टेक IDE बनाने वाली टीम ने बताया कि उन्होंने डेमन पर विचार किया, लेकिन फिर हर लॉन्च पर सख़्त अपडेट चेक चुना: अगर ऐप पुराना है तो वह बताता है और स्टार्टअप पर अपडेट कर लेता है, और अगर आपको यह पसंद नहीं, तो आप उसे चलाना बंद कर सकते हैं। यह एक वैध डिज़ाइन है।
लेकिन 'हमें अपडेट चाहिए' का मतलब यह नहीं कि 'हमें एक लगातार चलने वाला डेमन चाहिए जो आपके ध्यान न देने पर खुद को अपडेट करता रहे।' बीच में बहुत सारे विकल्प हैं:
- इन्वोकेशन पर जाँच करें। CLI शुरू होने पर वर्ज़न मिलाएँ, एक सूचना दिखाएँ, और अगली बार चलने पर अपडेट करें। Homebrew, gh और कई दूसरे टूल यही करते हैं।
- पैकेज मैनेजर से अपडेट करें। आपने npm से इंस्टॉल किया था, तो npm से ही अपडेट करें। यूज़र के पास पहले से एक ऐसा तंत्र है जिसे वह समझता है और जिसे वह पिन, ऑडिट और लॉक कर सकता है।
- डेमन ऑप्ट-इन हो, डिफ़ॉल्ट बंद। जिन यूज़र्स को बिना रुकावट के ताज़ा वर्ज़न चाहिए, उन्हें डेमन एक डॉक्यूमेंटेड विकल्प के रूप में दें।
- पुराने वर्ज़न हटाएँ। हर पिछली बाइनरी को तब तक रखना जब तक वह किसी का 12 GB डिस्क न खा ले, अपडेट की रणनीति नहीं है; यह एक लीक है।
टीमें सेल्फ-अपडेटर की ओर इसलिए जाती हैं क्योंकि असली वजह स्पीड नहीं, नियंत्रण है। पैकेज-मैनेजर अपडेट यूज़र के lockfile, mirrors और अप्रूवल वर्कफ़्लो का सम्मान करता है। सेल्फ-अपडेटर इन सबको बायपास कर देता है। जब कोई विक्रेता सेल्फ-अपडेट वाले रास्ते पर ज़ोर देता है, तो वह असल में बता रहा होता है कि उसे आपके change management से ज़्यादा अपनी डिप्लॉयमेंट पाइपलाइन की परवाह है। जिस एंटरप्राइज़ में लॉगिंग के पहले से ब्लाइंड स्पॉट्स हों, वहाँ बिना रिव्यू का कोड डेवलपर क्रेडेंशियल्स के तहत चलने लगता है।

मिथक 4: “यह ओपन सोर्स है, कोड पढ़ सकते हैं”
ओपन सोर्स मदद करता है, पर असली समस्या हल नहीं करता, और वह है आपकी समीक्षा किए गए कोड और चल रहे कोड के बीच का अंतर। सेल्फ-अपडेटिंग डेमन का पूरा मकसद ही यह है कि आज आपकी मशीन पर जो बाइनरी है, वह वह नहीं है जो आपने इंस्टॉल की थी। वर्ज़न 0.157.0 का सोर्स पढ़ने से आपको यह नहीं पता चलता कि अगले मंगलवार को कौन सा build आएगा। जब तक आप हर चुपचाप होने वाले अपडेट पर signatures और reproducible builds की जाँच न करें, और ऐसा कोई नहीं करता, तब तक 'यह ओपन सोर्स है' सिर्फ़ एक दिलासा है।
एक दूसरी, ज़्यादा बारीक समस्या भी है: स्टेट और कॉन्फ़िगरेशन का आपस में उलझना। यूज़र्स जो Codex को declaratively मैनेज करने की कोशिश कर रहे थे (एक ने बताया कि nix-darwin के तहत यह विफल हो गया), उन्होंने पाया कि टूल एक ही डायरेक्टरी में कॉन्फ़िग और बदलने वाली रनटाइम स्टेट मिलाता है। इससे यह पिन, diff या ऑडिट करना असंभव हो जाता है कि क्या बदला। अच्छे Unix टूल्स यह सदियों से जानते हैं: कॉन्फ़िग ~/.config में, स्टेट ~/.local/state में, कैश ~/.cache में, और टूल कभी अपना कॉन्फ़िगरेशन खुद नहीं बदलता। अगर आप समझना चाहते हैं कि ऑडिट होने वाला रास्ता क्यों मायने रखता है, तो स्पेसिफ़िकेशन और इम्प्लीमेंटेशन के बीच का अंतर ठीक वही जगह है जहाँ ये सरप्राइज़ रहते हैं।
अगर आप अभी अपनी मशीन पर चल रही चीज़ों की जाँच करना चाहते हैं, तो इसमें केवल तीस सेकंड लगते हैं:
# What AI-tool daemons are alive right now?
ps auxww | grep -Ei 'codex|claude' | grep -v grep
# What's been accumulating on disk?
du -sh ~/.codex ~/.local/share/claude 2>/dev/null
# What launchd/systemd units did tools register?
ls ~/Library/LaunchAgents 2>/dev/null # macOS
systemctl --user list-units --type=service | grep -Ei 'codex|claude' # Linux
इसे अपने संगठन के कुछ डेवलपर लैपटॉप पर चलाइए। मैं गारंटी देता हूँ कि कम से कम एक व्यक्ति आउटपुट देखकर हैरान होगा।
मिथक 5: “सब यही करते हैं, तो ठीक ही होगा”
Claude Code भी पिछले बाइनरी वर्ज़न रखता है और बैकग्राउंड टास्क चलाता है। इसी चर्चा में यूज़र्स ने इसकी पुष्टि भी की। तो हाँ, यह एक इंडस्ट्री पैटर्न है, किसी एक विक्रेता की चूक नहीं। लेकिन 'सब यही करते हैं' कभी सुरक्षा का तर्क नहीं रहा; ऐसे ही बुरे नियम जम जाते हैं। पिछले कुछ सालों की supply-chain घटनाओं ने हमें सिखाया होना चाहिए कि डेवलपर मशीनें ज़्यादातर संगठनों में सबसे नरम लेकिन सबसे कीमती निशाना हैं: उनमें क्लाउड क्रेडेंशियल्स, साइनिंग keys और push access होते हैं, और वे इन्हीं विशेषाधिकारों के साथ बेहिसाब अनऑडिटेड कोड चलाती हैं।
उस मशीन पर आप जो भी हर समय चालू, नेटवर्क से जुड़ा, और खुद को बदलने वाला हिस्सा जोड़ते हैं, वह आपकी सबसे संवेदनशील क्रेडेंशियल्स की ओर खुलने वाली attack surface है। किसी लोकप्रिय dev टूल का समझौता हुआ update channel एक बुरा सपना है, क्योंकि उस अपडेट मैकेनिज़्म पर अंधाधुंध भरोसा किया जाता है। जितना ज़्यादा विक्रेता चुपचाप डेमन को सामान्य बनाएँगे, उतना ही हर एक डेमन निशाने के रूप में कीमती होता जाएगा।
और क्वालिटी का मानक भी मायने रखता है। यूज़र्स ने बताया कि Codex डेमन ऑटो-अपडेट के दौरान permissions बिगाड़ देता था, जिससे .git डायरेक्टरी read-only हो जाती थीं और काम वाली repos अटक जाती थीं। एक बग वाला डेमन सिर्फ़ पड़ा नहीं रहता; वह उन विशेषाधिकारों के साथ सक्रिय रूप से चीज़ें तोड़ता है जो आपने सोच-समझकर कभी दिए ही नहीं। 'सब यही करते हैं' और 'यह बग वाला है' मिलकर कोई भरोसा नहीं देते। यह एक पूर्वानुमान है।
एक सहमति-सम्मत अपडेट मैकेनिज़्म कैसा दिखता है
यह एक सुलझी हुई समस्या है। हमें नई तकनीक की ज़रूरत नहीं; हमें विक्रेताओं को सीधा और उबाऊ जवाब चुनने की ज़रूरत है। अगर मैं आज कोई AI CLI शिप करने वाली टीम के लिए requirements doc लिख रहा होता, तो वह कुछ ऐसा होता:
- डिफ़ॉल्ट रूप से कोई persistence नहीं। टूल बुलाए जाने पर चले और काम खत्म होने पर बंद हो जाए। कोई भी बैकग्राउंड हिस्सा ऑप्ट-इन हो, जिसे पहली बार चलने पर साफ़ तौर पर माँगा जाए।
- डॉक्यूमेंटेड, स्थिर kill switches। एक कॉन्फ़िग फ़्लैग और एक environment variable (जैसे
CODEX_NO_DAEMON=1) जो डॉक्यूमेंटेड, टेस्टेड हों और चुपचाप गायब न हों। - इंस्टॉल चैनल से अपडेट। npm से इंस्टॉल टूल्स npm से अपडेट हों। इन्वोकेशन पर सूचना दें; यूज़र के नीचे से अपनी ही बाइनरी कभी न बदलें।
- साइन किए हुए, वर्ज़न वाले रिलीज़ changelog के साथ। अगर आप updater भेजते हैं, तो artifacts साइन करें और यूज़र्स को वर्ज़न पिन करने और बदलावों का ऑडिट करने दें।
- सीमित डिस्क और साफ़ स्टेट विभाजन। अधिकतम एक पिछला वर्ज़न रखें, कॉन्फ़िग को स्टेट से अलग करें, और XDG नियमों का पालन करें।
- distro मॉडल का सम्मान करें। जैसा एक commenter ने कहा, distro packaging इसलिए है ताकि maintainers सॉफ़्टवेयर को टेस्ट करें और उपयोगकर्ताओं तक पहुँचने से पहले शरारतें हटाएँ। इससे लड़ें नहीं, उसी में प्रकाशित करें।
इनमें से कुछ भी एक तेज़ चलती टीम को किसी अर्थपूर्ण रूप से धीमा नहीं करता। यह बस सहमति को बातचीत के सामने ले आता है, जहाँ उसकी जगह है।
निष्कर्ष
असहज सच्चाई यह है कि AI coding टूल्स किसी भी पिछले developer tool से ज़्यादा भरोसा माँग रहे हैं: शेल access, आपके क्रेडेंशियल्स, आपका पूरा सोर्स ट्री। और वे 2008 के एडवेयर जैसी अपडेट स्वच्छता अपना रहे हैं। ये दोनों बातें सुरक्षित रूप से एक साथ नहीं रह सकतीं। जो CLI डिफ़ॉल्ट रूप से एक लगातार चलने वाला, खुद को अपडेट करने वाला डेमन इंस्टॉल करता है, उसने आपकी ओर से एक फ़ैसला ले लिया है, और वह फ़ैसला यह है कि विक्रेता की सुविधा आपकी अपनी मशीन पर आपके नियंत्रण से ऊपर है।
इसका विरोध कीजिए। फ़्लैग सेट कीजिए, अपनी मशीनों का ऑडिट कीजिए, issues दर्ज कीजिए, और उन टूल्स को चुनिए जिनके डिफ़ॉल्ट आपका सम्मान करते हैं। वही प्रवृत्ति जो लोगों को लॉक्ड प्लेटफ़ॉर्म की जगह sideloading की आज़ादी की ओर ले जाती है, यहाँ भी लागू होती है। आज जिन टूल्स को हम डेवलपर लैपटॉप पर बिना निगरानी चलने देते हैं, वही कल की supply-chain इंसिडेंट रिपोर्ट बनेंगे। अपडेट डिज़ाइन में सहमति कोई अच्छी-सी चीज़ नहीं है। यह पूरा तंत्र है।


