आज मैंने अपने marketing platform का पहला version open-source कर दिया।
इसका नाम STRAŦUM है। नौ AI agents, agency के लिए एक workspace जिसमें हर client का data अलग रहता है, दस भाषाएँ। मैंने इसे 2025 में बनाया, उस दौर में जब मैं खुद software लिखना सीख रहा था। फिर मैंने दूसरा version शुरू किया, और पहले वाले को अपने पास बंद करके रखने के बजाय मैंने उसे सबको दे दिया।
बाकी पढ़ने से पहले अगर खुद देखना चाहें: github.com/chandlernguyen/stratum-oss
git clone https://github.com/chandlernguyen/stratum-oss
अगर आप marketing teams चलाते हैं और वो repository कभी खोलने वाले नहीं हैं, तो सीधे आखिर में "अगर आप Code कभी नहीं पढ़ेंगे" पर चले जाइए। वो section आपके लिए ही है, और छोटा है।
मैं साफ़-साफ़ बताना चाहता हूँ कि वो repository असल में क्या है, क्योंकि "open source" का मतलब कई चीज़ें हो सकता है — और उनमें से ज़्यादातर इससे बड़ा दिखाती हैं जो यह असल में है।
मैंने असल में publish क्या किया
STRAŦUM v1 publish हो चुका है और actively develop नहीं हो रहा। Code MIT licence के तहत public है। न कोई roadmap, न release schedule, न support का कोई वादा — README में यही लिखा है, और contributing guide में दोबारा।
यह reference implementation के तौर पर publish किया गया है। यह पढ़ने की चीज़ है, fork करने की चीज़ है, या इससे टुकड़े ले लेने की चीज़ है। यह depend करने की चीज़ नहीं है। आगे जब dependencies बदलेंगी, इसे कोई maintain नहीं कर रहा — और repository उन open advisories को list करती है जिनके बारे में उसे पता है, बजाय इसके कि दिखावा करे कि वो मौजूद ही नहीं।
मैं यह नहीं कह रहा कि इसमें कभी कुछ बदलेगा ही नहीं। मैं इसे आगे develop नहीं कर रहा, तो plan करते वक्त यह मान लीजिए कि यह जैसा है वैसा ही रहेगा — लेकिन लोग जो भेजते हैं वो मैं पढ़ता हूँ, और अगर कोई bug बताए या ऐसा सुझाव दे जिससे code ज़्यादा साफ़ हो जाए, तो मैं यह दिखावा नहीं करूँगा कि मैंने देखा ही नहीं।
इसे publish करने का मतलब यह भी था कि साबित करना पड़े कि साथ में कुछ confidential नहीं गया। Repository में एक script है जो हर tracked file को credentials, private keys, provider tokens और production identifiers के लिए scan करती है, और CI में सबसे पहला job वही चलता है — tests से पहले, क्योंकि leak हुई key push होते ही history का हिस्सा बन जाती है, और बाद में उसे delete करने से वो वापस नहीं होता।
इसमें क्या-क्या है:
- नौ agents — strategy, persona, content, performance intelligence, competitive intelligence, campaign planning, client success, और दो और। हर एक एक base agent का subclass है, और सब एक ही prompt structure, tool registry और progressive context साझा करते हैं।
- दो Postgres schemas। अलग-अलग businesses का data एक में रहता है, agencies का दूसरे में, और isolation की boundary Row Level Security है।
- दस locales, जहाँ locale एक header में API तक जाता है, ताकि generate हुआ metadata interface की भाषा से मेल खाए।
- एक demo mode, जिसके लिए किसी API key की ज़रूरत नहीं। Agents model को call करने के बजाय साफ़ label किया हुआ canned output लौटाते हैं, ताकि आप बिना किसी provider account के पूरी application click-through कर सकें।
अगर आप इसका अपना version बनाना चाहते हैं
यही वो इस्तेमाल है जो मैं सबसे ज़्यादा देखना चाहूँगा, तो इसे सीधे कह देना बेहतर है, बजाय इसके कि बात इशारे में छूट जाए।
अगर आपको असल में अपना marketing agent system चाहिए — अपने agents, अपने prompts, अपना schema, ऊपर अपना product — तो repository fork कीजिए और बनाइए। MIT licence इसी के लिए है, और यही इसका मक़सद है, कोई loophole नहीं। Licence file रखने के अलावा attribution की कोई ज़रूरत नहीं, और मुझसे पूछने की भी ज़रूरत नहीं। जो हिस्से काम के हों वो ले लीजिए, जो काम के न हों वो फेंक दीजिए, और जिससे आप सहमत न हों उसे बदल दीजिए।
इसके एक दर्जन अलग-अलग versions देखना मुझे उस एक version से ज़्यादा पसंद है जिसे सिर्फ़ मैंने ही छुआ हो।
v1 को publish क्यों किया, अपने पास रखने के बजाय
मैंने इसे दस महीने अपने पास रखा, क्योंकि मुझे लगा कि जिस v1 पर मैंने काम करना बंद कर दिया है, वो किसी को चाहिए ही नहीं। वो अनुमान गलत था — और वो अनुमान क्यों गलत था, यह repository से भी ज़्यादा कीमती है।
दूसरा version इससे अलग रास्ते पर है। जो मैं अब बना रहा हूँ, वो इस codebase से बहुत मिलता नहीं, और वो इसका diff नहीं होगा। v1 को private रखने का मतलब होता कि वो धीरे-धीरे एक ऐसा museum piece बन जाता जहाँ कोई आ ही नहीं सकता।
इससे अच्छी वजह यह है कि एक चलती हुई multi-tenant agentic application, किसी architecture diagram से ज़्यादा काम की चीज़ है। जब मैं सीख रहा था, तो मेरी मदद conceptual explainer से नहीं हुई — मदद तब हुई जब मुझे एक असली project मिला और मैंने पढ़ा कि किसी और ने उसे असल में कैसे जमाया था। जो reasoning explainer में खो जाती है, वही सबसे ज़्यादा मायने रखती है।
Repository के architecture notes में मैंने चार चीज़ें लिखीं जो मैंने गलत कीं और दोबारा नहीं करूँगा — और चारों को वहीं रहने दिया। पहली एक security bug है।
वो गलती जो ship हो गई
एक table बिना Row Level Security on किए बाहर चला गया।
public.notification_push_deliveries उस line के बिना बनाया गया जो RLS enable करती है, और उसे anonymous और authenticated roles को पूरे privileges के साथ grant कर दिया गया — TRUNCATE समेत — जबकि कोई policy define ही नहीं थी। यह उसी schema में है जिसे Data API expose करती है, और anonymous key browser bundle के अंदर ही ship होती है। तो उस दौरान, जिसके पास भी वो key हो, वो इस table को पढ़ सकता था या बदल सकता था। इसमें push device identifiers रहते हैं, जिसने इसे सैद्धांतिक नहीं, बल्कि असली data-exposure की समस्या बना दिया।
यह मुझे एक security review में मिला। किसी bug report में नहीं, और testing में भी नहीं — क्योंकि application पूरे समय बिल्कुल ठीक चल रही थी। जब किसी table में RLS नहीं होती, तो कोई error नहीं आता। Queries चल जाती हैं, feature काम करता है, और जो permission होनी ही नहीं चाहिए थी वो बस वहीं पड़ी रहती है, कुछ दिखता नहीं — जब तक कोई देख न ले।
अब यह बंद है। Table पर RLS on है और कोई policy नहीं है, और browser roles के grants revoke कर दिए गए हैं — तो जो request कभी rows लौटाती थी, वो अब permission error बनकर आती है। मैं इसे जानबूझकर past tense में लिख रहा हूँ: यह बताता है कि code कैसा दिखता था, यह नहीं कि आज कैसा दिखता है।
यही वो हिस्सा है जिस पर मैं साफ़ रहना चाहता हूँ: यह कोई design decision नहीं था जो मैंने सही लिया। यह एक regression था जो मैंने गलत किया, और बाद में पकड़ा।
तो मैंने अपनी memory पर भरोसा करना बंद कर दिया
इसके बाद मैंने जो किया, इस पूरे काम में बस वही एक चीज़ है जिसे मैं भरोसे के साथ किसी और को सौंप सकता हूँ।
मैंने एक test लिखा जो किसी खास table का नाम नहीं लेता। वो schema को चलकर rule check करता है: exposed schema की हर table में Row Level Security on हो, और कोई भी tenant-scoped materialised view browser role से readable न हो। अगर अगले महीने मैं कोई table जोड़ूँ और भूल जाऊँ, तो test fail होगा — और fail उसी चीज़ पर होगा जो मैं भूला, न कि उस list पर जो मैंने याद रहते हुए लिखी थी।
दो ईमानदार caveats, और मैं चाहूँगा कि पाठक ये मेरे खिलाफ़ उठाएँ, बजाय इसके कि बाद में खुद पता चले:
- उस check का materialised-view वाला हिस्सा
publicschema को cover करता है,agencyschema को नहीं। Agency की तरफ़ एक exposure है जो मैंने अब तक बंद नहीं की। - जब test database तक नहीं पहुँच पाता, तो वो खुद को skip कर देता है। Skip हुआ test green दिखता है, यानी एक टूटा हुआ environment एक fail होते invariant को छिपा सकता है।
अगर इस पूरे काम से मैंने एक आदत सीखी है, तो यह: जब इस तरह का bug मिलता है, तो मैं वो test लिखता हूँ जो इसे पकड़ लेता — और उसे rule के खिलाफ़ लिखता हूँ, न कि उस one object के खिलाफ़। वो test जिसमें उन तीन objects के नाम हैं जो मुझे याद थे, सिर्फ़ उन तीन की हिफ़ाज़त करता है। जो test rule check करता है, वो उस object की भी हिफ़ाज़त करता है जो मैं अगले हफ्ते जोड़कर भूल जाऊँगा।
दूसरा trap
एक दूसरा भी है, जो मैंने design से नहीं, किस्मत से सही किया — और vendor conversations में यही सबसे ज़्यादा सुनने को मिलता है।
Client-side filter कोई boundary नहीं होती। अगर आपकी application browser में organisation के हिसाब से rows filter करती है — .eq('org_id', ...) वगैरह — तो isolation user की machine पर चल रहा है, यानी उसे developer tools से हटाया जा सकता है। जो चीज़ हटाई जा सकती है, वो display preference है, security control नहीं। Row visibility या तो database में enforce होनी चाहिए, या ऐसे server endpoint के पीछे जिसे caller reach around न कर सके।
Materialised views इस समस्या के अजीब रिश्तेदार हैं। इन पर Row Level Security लग ही नहीं सकती। किसी materialised view पर SELECT grant हर tenant की rows लौटाता है, और migration में वो बिल्कुल वैसा ही दिखता है जैसा किसी table पर वही grant — जहाँ policies उसे रोक भी लेतीं। इसी वजह से repository हर tenant-scoped चीज़ पर browser-role grants revoke कर देती है, जब भी वो materialise हो।
वो एक जो मैंने अभी पूरा नहीं किया
Row Level Security TRUNCATE को रोक नहीं सकती। यह table-level privilege है, row-level नहीं, तो policies उस पर लागू ही नहीं होतीं। Repository के baseline grants browser roles को बड़ी तादाद में tables पर ALL दे देते हैं — जिसमें TRUNCATE भी शामिल है — और उसके बाद उसे कोई संकरा नहीं करता। Materialised views के grants revoke हो जाते हैं। ये नहीं होते। तो ऐसी tables हैं जहाँ browser role के पास एक ऐसा privilege है जो उस boundary के बाहर बैठा है जिसका ज़िक्र मैं इस पूरे section में कर रहा हूँ।
व्यवहार में यह latent है, खुला दरवाज़ा नहीं: Data API में TRUNCATE जैसा कोई verb नहीं है, browser roles सीधे database से connect नहीं कर सकते, और आम deployment में database port expose नहीं होता। यह hygiene की समस्या है। लेकिन इस post के शुरू वाले bug से इसका shape एक ही है — एक privilege जो चुपचाप अपनी वजह से ज़्यादा ज़िंदा रह जाता है — और मैं खुद उसकी तरफ़ इशारा करना बेहतर समझता हूँ, बजाय इसके कि पाठक उसे खोजे और सोचे कि मुझे पता था या नहीं। इसके लिए दोनों schemas पर revoke चाहिए, और एक test जो assert करे कि किसी browser role के पास ऐसा privilege न हो जो RLS को bypass करता हो।
जो मैं दोबारा नहीं करूँगा
दो parallel schemas ने बहुत सारी DDL duplicate कर दी। Agency और individual-business data के structures parallel हैं, बजाय इसके कि एक table हो और उसमें tenant discriminator column। Separation सच में ज़्यादा साफ़ है। लेकिन duplication ने maintenance में जितना खाया, वो discriminator column से ज़्यादा पड़ा — और अगली बार मैं दूसरा फैसला करूँगा।
Manual function calling में बहुत code लगता है। Agent loop tool calls खुद handle करता है, provider के automatic function calling के बजाय — जिससे streaming और tool execution application के control में रहते हैं। कीमत यह है कि application को function-result parts खुद assemble करने पड़ते हैं, और मौजूदा models पर उन parts में function name के साथ call id भी होनी चाहिए। id छोड़ दीजिए, तो schema error नहीं मिलेगा। ऐसा कुछ मिलेगा जो लगेगा कि model ही flaky हो रहा है — और वो दोपहर बहुत ज़्यादा खराब होती है। अगर अब किसी higher-level API से tools के साथ streaming मिलती है, तो यह trade दोबारा सोचने लायक है।
Migration chain 321 files तक पहुँच गई। इनमें बड़ा हिस्सा fix_, _v2 और remove_ नाम का था, क्योंकि मैं जो लिख चुका था उसे edit करने के बजाय सुधार जोड़ता जा रहा था। Schema की असली हालत सिर्फ़ शुरू से history replay करके ही पता चल सकती थी। उस दौर के बारे में मैंने जो posts लिखे, वो code के हक़ से ज़्यादा confident थे — नवंबर 2025 में मैंने लिखा था कि तैंतीस migrations ने multi-tenancy को "आखिरकार हल" कर दिया, और उसके बाद महीनों तक corrective migrations लिखता रहा।
Frontend API के shapes पर बिना validate किए भरोसा करता है। अंदर आते वक्त validation पूरी है — backend हर request को Pydantic से parse करता है — और बाहर जाते वक्त कोई नहीं। Browser response लेता है और उसे सच मान लेता है। एक shared schema होती तो drift तब ही पकड़ में आ जाता जब कोई field अपना shape बदलती, बजाय इसके कि वो blank screen बनकर सामने आए। ऊपर की तीनों के साथ मिलाकर, ये चार चीज़ें हैं जो architecture notes के मुताबिक़ मैं अलग तरीके से करूँगा।
Publish हुई repository migration chain को बीस layered migrations में दोबारा बनाती है, concern के हिसाब से grouped — tables, फिर domain के हिसाब से grouped functions, views, indexes, triggers, policies, grants, scheduled jobs, और आखिर में एक hardening pass। यह लगभग सच है, पूरी तरह सच नहीं — और यह बताना ईमानदारी है कि कहाँ फिसलन है: इन बीस में से एक ऐसा catch-all है जिसे खुद माना गया है, उन functions के लिए जो किसी category में नहीं बैठे, और table की layer उस तरह बँटी ही नहीं जैसा उसके filenames बताते हैं। जिस file का नाम shared schema पर है, वो आठों agency tables भी बनाती है, और जिस file का नाम agency schema पर है, उसमें table definitions बिल्कुल नहीं हैं। Layering असली है; labels perfect नहीं।
बँटवारे में जो चीज़ सही बैठती है, वो वही है जो इसे पढ़ने के लिए मायने रखती है: schema सिर्फ़ एक reorganisation है, जिसे पहले और बाद में dump करके verify किया गया — दोनों dump tool के random token के अलावा byte-identical निकले।
बस उसी verification की वजह से मैं इसे छूने को तैयार हुआ।
क्या बचा रहा
Row Level Security असली boundary के तौर पर, न कि किसी feature के तौर पर जिसे on करना होता है। जब design उसके इर्द-गिर्द बन जाता है, तो isolation checklist का एक item नहीं रह जाता — वो system का गुण बन जाता है।
Writes routed database functions से होकर जाते हैं। Application code तय नहीं करता कि किस schema को छूना है। वो एक function call करता है जो organisation type देखकर dispatch करता है, तो यह फैसला एक ही जगह रहता है, जहाँ कोई नया code path उसे करना भूल नहीं सकता।
Signup client input को नज़रअंदाज़ करता है। Provisioning trigger client से आए organisation id या role को नहीं मानता, क्योंकि वो data user के control में है। वो एक नया organisation और एक default owner role बनाता है। छोटी सी बात है, गलत करना आसान है, और जब गलत होती है तो महँगी पड़ती है।
Lazy client construction। Services अपना provider client पहले इस्तेमाल पर बनाती हैं, import पर नहीं। यह style preference जैसा लगता है, है नहीं: कई services module import पर ही बन जाती हैं, तो eager construction का मतलब था कि application import करने के लिए भी API key चाहिए, और failure provider के SDK से एक अपारदर्शी error के रूप में सामने आती थी, कुछ शुरू होने से पहले ही। इसे lazy बनाने से ही demo mode मुमकिन हुआ, और उसी से कोई अजनबी बिना कुछ खर्च किए project को परख सकता है।
यह आखिरी फैसला वो है जिससे मैं सबसे ज़्यादा खुश हूँ — और मैंने यह उस वजह से नहीं किया जो बाद में मायने रखने लगी। मैंने यह crash रोकने के लिए किया था।
अगर आप Code कभी नहीं पढ़ेंगे
जब मैं agency की तरफ़ था और ऐसा software खरीदता था, तब मुझे यही section चाहिए होता। इसलिए इसमें कोई code नहीं है।
यहाँ से जो लेकर जाने लायक है, वो है "हम account के हिसाब से filter करते हैं" और "database किसी दूसरे account की rows लौटा ही नहीं सकता" के बीच का फ़र्क़।
मैंने अपने करियर का ज़्यादातर हिस्सा platforms खरीदते हुए बिताया है और पिछले कुछ साल उन्हें बनाते हुए, और यही फ़र्क़ वो था जो मुझे तब तक समझ नहीं आया जब तक मैंने इसका गलत version ship नहीं कर दिया। एक नियम है जिसे browser follow करता है। दूसरा नियम है जिसे browser तोड़ नहीं सकता। ज़्यादातर tools में पहला होता है, और वो उसे दूसरे की भाषा में बताते हैं।
जब आप ऐसा platform परख रहे हों जिसमें कई clients का data रहेगा — competitive intelligence, performance data, audience definitions, जो भी हो — तो सवाल "क्या यह secure है" नहीं है। उसका जवाब सब हाँ कहते हैं। सवाल यह है: separation कहाँ enforce होता है, और अगर कोई developer filter हटा दे तो क्या होगा?
अच्छे जवाब दो हैं। या तो यह database में enforce होता है, signed-in user की identity से बँधी policies के ज़रिए, या ऐसे server endpoint के पीछे जिसे browser reach around नहीं कर सकता। जिस भी जवाब में browser आता है, वो ना है।
अच्छे जवाब ऐसे लगते हैं: policy table पर है और user के session से keyed है; browser उस table को सीधे query ही नहीं करता; यह रहा वो test जो इसे साबित करता है। कम काम के जवाब ऐसे लगते हैं: हमारी application account के हिसाब से filter करती है; data encrypted है; हम SOC 2 compliant हैं। ये सब सच भी हो सकते हैं, पर इनमें से कोई सवाल का जवाब नहीं देता।
एक line की बात है, और यह vendor security review में आराम से फिट हो जाती है — मैं इसे वहीं रखूँगा। जवाब बता देता है कि multi-tenancy शुरू से design में थी या बाद में जोड़ी गई।
अक्सर पूछे जाने वाले सवाल
Private repository में पड़ा रहने देने के बजाय इसे publish क्यों किया?
क्योंकि public चीज़ को कोई check कर सकता है, private को नहीं। इससे पहले जो posts मैंने इसे बनाने के बारे में लिखे, उनमें दावे थे; migrations, policies और tests वाली repository एक ऐसी चीज़ है जिसे पाठक खुद verify कर सकता है — उन हिस्सों समेत जो मैंने गलत किए। Architecture notes में "Tradeoffs, and what I would do differently" नाम का एक section है, और repository इसी रूप में मौजूद होने की वजह वही है।
क्या दूसरा version open source होगा?
नहीं। यह private में develop हो रहा है, और उम्मीद नहीं है कि इसका codebase इससे मिलेगा। मैं यह साफ़ कह देना पसंद करूँगा, बजाय इसके कि बात गोलमोल छोड़ूँ और लोग इसे clone करके roadmap की उम्मीद लगाए बैठें।
क्या मैं इसे production में इस्तेमाल कर सकता हूँ?
मैं नहीं करूँगा। यह एक reference है, product नहीं। Seed data में दिए demo credentials सिर्फ़ local इस्तेमाल के लिए हैं, support का कोई वादा नहीं है, और आगे dependencies बदलने पर इसे कोई ठीक नहीं कर रहा। यह पढ़ने और इससे उधार लेने के लिए अच्छी चीज़ है, और इस पर business चलाने के लिए बुरी चीज़।
इसे try करने के लिए AI key चाहिए?
नहीं। यह demo mode में शुरू होता है, जहाँ agents model को call करने के बजाय साफ़ label किया हुआ canned output लौटाते हैं। आप पूरी application click-through कर सकते हैं — हर agent, agency के client flows, language switcher — बिना किसी key के और बिना कुछ खर्च किए। असली model calls पर switch करना एक setting और एक key की बात है। पहली बार मुझे दस मिनट से ज़्यादा लगे थे: इसके लिए Docker चलता हुआ, Node, Python, Poetry और Supabase CLI चाहिए, और सबसे धीमा हिस्सा एक बड़ा download है।
इसे बनाते वक्त मैंने इसके बारे में बहुत लिखा, और शुरू करने के लिए दो posts ये हैं — मैंने day two पर multi-tenancy क्यों बनाया और जब मैंने इसे day sixty-seven पर दोबारा बनाया तो क्या हुआ। अगर इनमें से किसी एक पर ही आपका समय लगाना बने, तो वो दूसरा है — उसी में architecture गलत निकला था।
Code यहाँ है github.com/chandlernguyen/stratum-oss, और जो test उस गलती की निगरानी करता है जो मैंने ship की, वो tests/automated/test_rls_coverage.py में है।
अगर आपने भी कोई multi-tenant system ship किया है और कोई तीसरा silent trap पकड़ा है जिसका ज़िक्र मैंने नहीं किया, तो मुझे सच में सुनना अच्छा लगेगा — वही इकट्ठा करने लायक होते हैं।
Feedback, suggestions, और v1 का क्या होगा
मैं नहीं चाहता कि यह एकतरफ़ा broadcast बनकर रह जाए, तो यह ईमानदार version है कि आप क्या उम्मीद कर सकते हैं।
मुझे क्या अच्छा लगेगा: अगर repository में कुछ सीधे-सीधे गलत है, तो bug reports। जो हिस्से ज़्यादा साफ़, ज़्यादा आसान, या कम code में हो सकते हैं, उन पर suggestions। ऐसे लोगों के notes जिन्होंने इसे चलाने की कोशिश की और README में न बताई गई कोई चीज़ अटकी। Pull requests, अगर आपको कोई असली problem मिले और आप उसे ठीक करना चाहें। और अगर आप इसे fork करके अपना कुछ बनाएँ, तो मुझे जानना अच्छा लगेगा कि आपने क्या बदला और क्यों — वही सबसे दिलचस्प feedback होता है, क्योंकि वो फैसले आपको असल में लेने पड़े।
मैं क्या वादा कर सकता हूँ: ज़्यादा कुछ नहीं, और यह कह देना मुझे इससे बेहतर लगता है कि कुछ और मतलब निकलने दिया जाए। यह कोई actively developed project नहीं है, मैं support desk नहीं चला रहा, और किसी response time का वादा नहीं कर सकता। कुछ suggestions पर मैं अमल करूँगा। कुछ पढ़कर सहमत होऊँगा, और उन तक कभी पहुँच नहीं पाऊँगा। यह उस side project की असली तस्वीर है जिसका successor पहले से मौजूद है।
v1 का क्या होगा: यह जैसा है वैसा ही published रहेगा। मैं इसे आगे develop नहीं कर रहा, तो नए releases की उम्मीद में plan मत बनाइए। पर मैं यह भी नहीं दिखाऊँगा कि यह सीलबंद है — code public है, licence आपको इसे किसी भी दिशा में ले जाने की इजाज़त देता है, और अगर कुछ टूटा हुआ है या सच में साफ़ नहीं है, तो सिद्धांत के नाम पर मैं उसे वैसा ही क्यों छोड़ूँ।
मुझ तक पहुँचने का सबसे आसान तरीक़ा repository पर issue है, या email — अगर आप इस बारे में सार्वजनिक नहीं होना चाहते।
बस, मेरी तरफ़ से अभी इतना।
शुभकामनाओं सहित, Chandler