चुनिंदा काम

Insomniac: Mac को लिड बंद रखते हुए जगाए रखो, बिना गरम किए

भूमिका
0→1 बनाया
स्टैक
Swift · SwiftUI · macOS · IOKit
लिंक्स

समस्या

मैं चाहता था कि मेरा Mac लिड बंद रखते हुए भी चलता रहे। डिम नहीं: असल में काम करता हुआ, रातभर एक AI एजेंट, एक Xcode आर्काइव, एक लंबा सिंक, लिड बंद, कोई एक्सटर्नल मॉनिटर नहीं। macOS इसे क्लैमशेल स्लीप कहता है, और उसे परवाह नहीं कि आपका काम बीच में है।

पेच मैकेनिज़्म में है। पॉपुलर कीप-अवेक टूल्स IOKit पावर असर्शन्स इस्तेमाल करते हैं, और वो क्लैमशेल स्लीप को तब तक नहीं रोकते जब तक आपके पास एक एक्सटर्नल डिस्प्ले, पावर, और एक कीबोर्ड न जुड़ा हो, ठीक वही सेटअप जिससे मैं बचना चाहता था। इकलौता लीवर जो बिना कुछ जोड़े काम करता है, वो एक प्रिविलेज्ड कमांड है: pmset disablesleep। तो पूरा प्रोडक्ट असल में एक ही चीज़ है, एक ख़तरनाक सिस्टम सेटिंग के इर्द-गिर्द एक सेफ़ रैपर, और बाकी सब कुछ उस एक लीवर को सेफ़ और सुखद तरीके से खींचने लायक बनाने के लिए है।

फ़ैसले

सेफ़्टी फ़ीचर है, जगे रहना नहीं। एक जेनेरिक पेड कीप-अवेक ऐप शुरू में ही मरा हुआ है: Amphetamine और caffeinate पहले से मुफ़्त में यह करते हैं। बिना सर्व किया गया एंगल था गर्मी। बंद लिड एयरफ़्लो को घोंटता है, और कोई मौजूदा टूल इसके बारे में एक शब्द नहीं कहता। तो Insomniac “जगे रहो” नहीं है, यह “मशीन को गरम किए बिना जगे रहो” है।

macOS जो ईमानदारी से एक्सपोज़ करता है उसे मापो, नकली डिग्रियाँ नहीं। लुभावना वर्ज़न एक CPU तापमान पढ़ता है और डिग्रियों में एक काउंटडाउन दिखाता है। पर Apple Silicon डाई तापमान पढ़ने का कोई सपोर्टेड तरीका एक्सपोज़ नहीं करता; जो कुछ भी ऐसा दावा करता है वो प्राइवेट कीज़ पढ़ रहा है जो मॉडलों के बीच टूटती हैं। तो मैंने ProcessInfo.thermalState (nominal, fair, serious, critical) पर बनाया, जिसे कोई एडमिन नहीं चाहिए और जो हमेशा के लिए सपोर्टेड है। और असली सुरक्षा एक अपफ़्रंट प्रेडिक्शन है ही नहीं: यह एक लाइव थर्मल कटऑफ़ है जो लिड बंद रहते हुए स्टेट पर नज़र रखती है और अगर यह बढ़े तो सेशन ऑटो-स्टॉप कर देती है। एक प्रेडिक्शन ग़लत हो सकता है; एक लाइव कटऑफ़ ग्राउंड ट्रुथ है।

एक आर्किटेक्चर जहाँ ख़तरनाक हिस्सा स्वैपेबल है। pmset को रूट के रूप में चलाने के दो रास्ते हैं: एक AppleScript प्रॉम्प्ट जो हर टॉगल पर पासवर्ड माँगता है (मामूली, पहले दिन काम करता है) और XPC पर एक प्रिविलेज्ड हेल्पर जो चुपचाप टॉगल करता है (प्रोडक्शन-ग्रेड, साइनिंग और एक पिन किए गए कॉन्ट्रैक्ट की ज़रूरत)। ऐप को किसी एक से जोड़ने के बजाय, मैंने दोनों को एक PowerControlling प्रोटोकॉल के पीछे छिपाया। मैंने पहले दिन पासवर्ड-प्रॉम्प्ट वर्ज़न शिप किया और बाद में साइलेंट हेल्पर बिना किसी कॉलर बदलाव के जोड़ा। हेल्पर लॉक्ड डाउन है: एक रूट डेमन के रूप में यह सिर्फ़ उन XPC कनेक्शन्स को स्वीकार करता है जो इस ऐप के आइडेंटिफ़ायर और Team ID से पिन किए हों।

सेफ़्टी इनवेरिएंट्स कोड द्वारा लागू किए जाते हैं। एक कीप-अवेक ऐप में एक विनाशकारी फ़ेल्योर है: काम ख़त्म होने के बाद स्लीप को डिसेबल्ड छोड़ देना। मैंने “स्लीप को कभी डिसेबल्ड न छोड़ो” को एक इनवेरिएंट माना और हर एग्ज़िट बंद किया। टॉगल ऑफ़, ऑटो-ऑफ़, थर्मल कटऑफ़, और बैटरी कटऑफ़ सब स्लीप रिस्टोर करते हैं। क्विट और लॉगआउट टर्मिनेशन को तब तक टालते हैं जब तक रिस्टोर पूरा न हो; ऐप स्लीप डिसेबल्ड रहते हुए मरने से इनकार करता है। एक हार्ड क्रैश इंटरसेप्ट नहीं किया जा सकता, तो अगले लॉन्च पर ऐप बिना किसी एक्टिव सेशन के स्लीप डिसेबल्ड पाता है और इसे रीसेट करने की पेशकश करता है। कोई “अनिश्चितकालीन” भी नहीं है: सबसे लंबा सेशन एक सख़्त 8-घंटे की सीमा है, क्योंकि “हमेशा के लिए” ठीक वही सेटिंग है जो एक मरा हुआ, गरम लैपटॉप बैग में छोड़ देती है।

ईमानदार UI, ईमानदार प्राइवेसी। ऐप सिर्फ़ मेन्यू-बार है। एडवाइज़री एक रिस्क लेवल (low, moderate, high) और एक सादा मैसेज दिखाती है, कभी वो डिग्रियाँ नहीं जिन्हें मैं ईमानदारी से नहीं पढ़ सकता, और वेदर नज सोच-समझकर सबसे कमज़ोर इनपुट है: एक गरम कमरा रिस्क बढ़ा सकता है, पर एक ठंडा कमरा एक गरम होते CPU को कभी सेफ़ नहीं बना सकता। वेदर लोकेशन IP जियोलोकेशन से आती है, सिटी-लेवल, तो कोई GPS परमिशन प्रॉम्प्ट नहीं; वेदर बंद करो और ऐप कुछ नहीं भेजता। कोई टेलीमेट्री नहीं, कोई एनालिटिक्स नहीं।

वो बग जो मुझे सिर्फ़ इसके साथ जीकर मिला। V1 ने Mac को जगाए रखा, पर स्क्रीन लिड बंद रहते हुए जलती रही, क्योंकि स्लीप डिसेबल करना macOS को इंटरनल डिस्प्ले बंद करने से भी रोक देता है। कीबोर्ड के ख़िलाफ़ जलता एक बैकलाइट बर्बाद बैटरी और गर्मी है, ठीक वही चीज़ जिससे ऐप बचाता है। मैंने एक लिड मॉनिटर जोड़ा जो ओपन-से-क्लोज़्ड एज पर फ़ायर होता है और डिस्प्ले को एक हानिरहित यूज़र-लेवल कमांड से स्लीप कराता है, प्रिविलेज्ड हेल्पर से सोच-समझकर अलग रखा गया। जिस चीज़ को इसकी ज़रूरत नहीं, उसके लिए लीस्ट प्रिविलेज।

अभी शिप करो, रफ़ एज को अपनाओ। कोर फ़ीचर को App Sandbox ऑफ़ चाहिए, जो Mac App Store को बाहर कर देता है, तो मैंने एक डायरेक्ट डाउनलोड शिप किया। पहले Apple की पेपरवर्क पर दिन बिताने के बजाय, मैंने अभी एक अन-नोटराइज़्ड बिल्ड शिप किया और नतीजतन आने वाली Gatekeeper चेतावनी को एक गाइडेड, एक-मिनट का स्टेप बनाया: इंस्टॉलर एक हाथ से बनाई सेटअप गाइड है, क्वारंटीन-क्लियरिंग कमांड ऐप के ठीक बगल में एक कॉपी करने लायक फ़ाइल के रूप में है, और ऐप हर लॉन्च पर अपना क्वारंटीन फ़्लैग हटा देता है ताकि चेतावनी कभी वापस न आए। पैकेजिंग स्क्रिप्ट एक सर्टिफ़िकेट मौजूद होते ही एक कमांड से री-साइन और नोटराइज़ कर देती है।

नतीजा

Insomniac लाइव है: एक मेन्यू-बार ऐप जो Mac को लिड-बंद जगाए रखता है, एक लाइव थर्मल कटऑफ़, एक बैटरी कटऑफ़, क्रैश रिकवरी, और एक साइन किए हेल्पर के ज़रिए साइलेंट टॉगलिंग के साथ। पूरी चीज़ दो नियमों पर टिकी है: ईमानदार रहो (असली मैकेनिज़्म, नकली डिग्रियों के बजाय रिस्क लेवल, एक कमज़ोर सिग्नल को कमज़ोर रखा) और रफ़ एज को छिपाने के बजाय अपनाते हुए तेज़ी से शिप करो। एक कीप-अवेक ऐप एक छोटी चीज़ है, पर यह एक ऐसी सेटिंग को छूता है जो हार्डवेयर को नुकसान पहुँचा सकती है, तो हर शॉर्टकट जो डेमो को ज़्यादा चमकदार बनाता, वो प्रोडक्ट को कम भरोसेमंद बनाता।