Skip to main content

title: आर्किटेक्चर description: “हुक हैंडलर, कॉन्फ़िग लोडिंग, और पॉलिसी मूल्यांकन आंतरिक रूप से कैसे काम करते हैं” icon: sitemap

यह दस्तावेज़ बताता है कि failproofai आंतरिक रूप से कैसे काम करता है: हुक सिस्टम एजेंट टूल कॉल को कैसे इंटरसेप्ट करता है, कॉन्फ़िग कैसे लोड और मर्ज किया जाता है, पॉलिसीज़ का मूल्यांकन कैसे होता है, और डैशबोर्ड एजेंट गतिविधि को कैसे मॉनिटर करता है।

अवलोकन

failproofai के दो स्वतंत्र सबसिस्टम हैं:
  1. हुक हैंडलर - एक तेज़ CLI सबप्रोसेस जिसे Claude Code हर एजेंट टूल कॉल पर आमंत्रित करता है। पॉलिसीज़ का मूल्यांकन करता है और एक निर्णय लौटाता है।
  2. एजेंट मॉनिटर (डैशबोर्ड) - एजेंट सेशन मॉनिटर करने और पॉलिसीज़ प्रबंधित करने के लिए एक Next.js वेब एप्लीकेशन।
दोनों सबसिस्टम ~/.failproofai/ और प्रोजेक्ट की .failproofai/ डायरेक्टरी में कॉन्फ़िग फाइलें साझा करते हैं, लेकिन वे अलग प्रक्रियाओं के रूप में चलते हैं और केवल फाइलसिस्टम के माध्यम से संचार करते हैं।

हुक हैंडलर

Claude Code के साथ एकीकरण

जब आप failproofai policies --install चलाते हैं, तो यह ~/.claude/settings.json में इस तरह की एंट्रीज़ लिखता है:
Claude Code फिर प्रत्येक टूल कॉल से पहले एक सबप्रोसेस के रूप में failproofai --hook PreToolUse को आमंत्रित करता है, stdin पर एक JSON पेलोड पास करता है।

पेलोड प्रारूप

PostToolUse इवेंट्स के लिए, पेलोड में टूल के आउटपुट के साथ tool_result भी होता है। हैंडलर 1 MB stdin सीमा लागू करता है। इस सीमा से अधिक पेलोड को त्याग दिया जाता है और सभी पॉलिसीज़ निहित रूप से अनुमति देती हैं।

प्रतिक्रिया प्रारूप

अस्वीकार (PreToolUse):
अस्वीकार (PostToolUse):
निर्देश (कोई भी इवेंट स्टॉप को छोड़कर):
स्टॉप इवेंट निर्देश:
  • एक्जिट कोड: 2
  • कारण stderr में लिखा जाता है (stdout में नहीं)
अनुमति:
  • एक्जिट कोड: 0
  • खाली stdout
संदेश के साथ अनुमति: allow(message) एक पॉलिसी को ऑपरेशन की अनुमति देते समय भी Claude को सूचनात्मक संदर्भ भेजने देता है। हुक हैंडलर stdout में निम्नलिखित JSON लिखता है (कॉन्फ़िग फाइल में नहीं — यह हैंडलर की Claude Code को प्रतिक्रिया है, जैसे अस्वीकार और निर्देश प्रतिक्रिया के समान):
  • एक्जिट कोड: 0 (ऑपरेशन की अनुमति है)
  • जब कई पॉलिसीज़ संदेश के साथ allow लौटाती हैं, तो उनके संदेश नई पंक्तियों से जुड़े होते हैं एक एकल additionalContext स्ट्रिंग में
  • यदि कोई पॉलिसी संदेश प्रदान नहीं करती है, तो stdout खाली है (पहले जैसे)

प्रोसेसिंग पाइपलाइन

src/hooks/handler.ts पूरी पाइपलाइन लागू करता है:
पूरी प्रक्रिया बिना LLM कॉल के विशिष्ट पेलोड्स के लिए 100ms में चलती है।

कॉन्फ़िग लोडिंग

src/hooks/hooks-config.ts तीन-स्कोप कॉन्फ़िग लोडिंग लागू करता है।
मर्ज लॉजिक:
  • enabledPolicies - तीनों फाइलों में विस्तारित यूनियन
  • policyParams - प्रति-पॉलिसी की, जो फाइल पहले इसे परिभाषित करती है वह पूरी तरह जीतती है
  • customPoliciesPath - जो फाइल पहले इसे परिभाषित करती है वह जीतती है
  • llm - जो फाइल पहले इसे परिभाषित करती है वह जीतती है
वेब डैशबोर्ड पढ़ने और लिखने के लिए readHooksConfig() (केवल ग्लोबल) का उपयोग करता है, क्योंकि इसे प्रोजेक्ट cwd के साथ आमंत्रित नहीं किया जाता है।

पॉलिसी मूल्यांकन

src/hooks/policy-evaluator.ts पॉलिसीज़ को क्रम में चलाता है। प्रत्येक पॉलिसी के लिए:
  1. पॉलिसी की params स्कीमा देखें (यदि इसके पास है)।
  2. मर्ज की गई कॉन्फ़िग से policyParams[policy.name] पढ़ें।
  3. यूजर-प्रदान किए गए मूल्यों को स्कीमा डिफ़ॉल्ट्स के ऊपर मर्ज करें ctx.params उत्पन्न करने के लिए।
  4. policy.fn(ctx) को हल किए गए संदर्भ के साथ कॉल करें।
  5. यदि परिणाम deny है, तो तुरंत रोकें और वह निर्णय लौटाएं।
  6. यदि परिणाम instruct है, तो संदेश जमा करें और जारी रखें।
  7. यदि परिणाम allow है, तो अगली पॉलिसी पर जाएं।
सभी पॉलिसीज़ चलने के बाद:
  • यदि कोई deny लौटाया गया था, तो अस्वीकार प्रतिक्रिया उत्सर्जित करें।
  • यदि कोई instruct रिटर्न एकत्र किए गए थे, तो सभी संदेशों को जुड़े हुए एकल निर्देश प्रतिक्रिया उत्सर्जित करें।
  • अन्यथा, अनुमति प्रतिक्रिया उत्सर्जित करें (खाली stdout, एक्जिट 0)।

बिल्ट-इन पॉलिसीज़

src/hooks/builtin-policies.ts सभी 39 बिल्ट-इन पॉलिसीज़ को BuiltinPolicyDefinition ऑब्जेक्ट्स के रूप में परिभाषित करता है:
पॉलिसीज़ जो params स्वीकार करती हैं, प्रत्येक पैरामीटर के लिए प्रकार और डिफ़ॉल्ट्स के साथ एक PolicyParamsSchema घोषित करती हैं। पॉलिसी मूल्यांकनकर्ता fn को कॉल करने से पहले हल किए गए मूल्यों को ctx.params में इंजेक्ट करता है। पॉलिसी फ़ंक्शन ctx.params को पढ़ते हैं null-गार्डिंग के बिना क्योंकि डिफ़ॉल्ट्स हमेशा पहले लागू होते हैं। पॉलिसीज़ के अंदर पैटर्न मिलान पार्स किए गए कमांड टोकन (argv) का उपयोग करता है, कच्ची स्ट्रिंग मिलान नहीं। यह शेल ऑपरेटर इंजेक्शन के माध्यम से बाईपास को रोकता है (उदाहरण के लिए, sudo systemctl status * के लिए एक पैटर्न कमांड में ; rm -rf / जोड़कर बाईपास नहीं किया जा सकता)।

कस्टम पॉलिसीज़

src/hooks/custom-hooks-registry.ts एक globalThis-समर्थित रजिस्ट्री लागू करता है:
src/hooks/custom-hooks-loader.ts यूजर की पॉलिसी फाइल लोड करता है:
  1. कॉन्फ़िग से customPoliciesPath पढ़ें; यदि अनुपस्थित है तो छोड़ें।
  2. पूर्ण पथ में हल करें; फाइल अस्तित्व की जांच करें।
  3. सभी from "failproofai" आयातों को वास्तविक dist पथ में फिर से लिखें ताकि customPolicies समान globalThis रजिस्ट्री को हल करे।
  4. ESM संगतता सुनिश्चित करने के लिए पारगमन स्थानीय आयातों को पुनरावर्ती रूप से फिर से लिखें।
  5. अस्थायी .mjs फाइलें लिखें और एंट्री फाइल को import() करें।
  6. पंजीकृत हुक्स पुनः प्राप्त करने के लिए getCustomHooks() को कॉल करें।
  7. finally ब्लॉक में सभी अस्थायी फाइलें साफ करें।
किसी भी त्रुटि पर (फाइल नहीं मिली, सिंटैक्स त्रुटि, आयात विफलता), त्रुटि को ~/.failproofai/hook.log में लॉग किया जाता है और लोडर एक खाली सरणी लौटाता है। बिल्ट-इन पॉलिसीज़ प्रभावित नहीं होती हैं। कस्टम पॉलिसीज़ का मूल्यांकन सभी बिल्ट-इन पॉलिसीज़ के बाद किया जाता है। एक कस्टम पॉलिसी deny अभी भी आगे की कस्टम पॉलिसीज़ को शॉर्ट-सर्किट करता है (लेकिन इस बिंदु पर सभी बिल्ट-इन्स पहले ही चल चुकी हैं)।

गतिविधि लॉगिंग

प्रत्येक हुक इवेंट के बाद, हैंडलर ~/.failproofai/hook-activity.jsonl में एक JSONL पंक्ति जोड़ता है:
प्रत्येक पॉलिसी के लिए एक पंक्ति जिसने एक गैर-अनुमति निर्णय दिया। अनुमति निर्णय लॉग नहीं किए जाते हैं (फाइल को छोटा रखने के लिए)।

डैशबोर्ड आर्किटेक्चर

डैशबोर्ड एक Next.js 16 एप्लीकेशन है जो App Router का उपयोग करता है React Server Components और Server Actions के साथ।
डेटा फ़्लो:
  • पेज कंपोनेंट्स प्रोजेक्ट/सेशन डेटा सीधे फाइलसिस्टम से पढ़ने के लिए lib/projects.ts और lib/log-entries.ts को कॉल करते हैं (पढ़ने के लिए कोई API परत नहीं)।
  • पॉलिसीज़ पेज सभी म्यूटेशन्स (टॉगल, पैरामीटर अपडेट, इंस्टॉल/निकालें) के लिए Server Actions का उपयोग करता है।
  • सेशन व्यूअर Claude के JSONL ट्रांसक्रिप्ट प्रारूप को पार्स करता है और संदेशों और टूल कॉल की एक समयरेखा प्रदान करता है।
मुख्य डिजाइन निर्णय:
  • कोई डेटाबेस नहीं - सभी स्थायी स्थिति सादी फाइलों में है (~/.failproofai/, ~/.claude/projects/)।
  • म्यूटेशन्स के लिए Server Actions - CRUD ऑपरेशन्स के लिए कोई REST API आवश्यक नहीं।
  • पढ़ने वाले पेजों के लिए React Server Components - तेज़ प्रारंभिक लोड, डेटा फेचिंग के लिए कोई क्लाइंट बंडल नहीं।
  • क्लाइंट कंपोनेंट्स केवल जहां इंटरएक्टिविटी आवश्यक है (पॉलिसी टॉगल्स, गतिविधि खोज, लॉग व्यूअर)।

फाइल लेआउट