> ## Documentation Index
> Fetch the complete documentation index at: https://exosphere-auto-translate-docs-20260624-1149.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

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

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

***

## अवलोकन

failproofai के दो स्वतंत्र सबसिस्टम हैं:

1. **हुक हैंडलर** - एक तेज़ CLI सबप्रोसेस जो Claude Code हर एजेंट टूल कॉल पर चलाता है। पॉलिसीज़ का मूल्यांकन करता है और एक निर्णय देता है।
2. **एजेंट मॉनिटर (डैशबोर्ड)** - एजेंट सेशन की निगरानी और पॉलिसीज़ को प्रबंधित करने के लिए एक Next.js वेब एप्लिकेशन।

दोनों सबसिस्टम `~/.failproofai/` और प्रोजेक्ट की `.failproofai/` डायरेक्टरी में कॉन्फ़िग फ़ाइलें साझा करते हैं, लेकिन वे अलग-अलग प्रक्रियाओं के रूप में चलते हैं और केवल फ़ाइलसिस्टम के माध्यम से संचार करते हैं।

***

## हुक हैंडलर

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

जब आप `failproofai policies --install` चलाते हैं, तो यह `~/.claude/settings.json` में इस तरह की प्रविष्टियाँ लिखता है:

```json theme={null}
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "failproofai --hook PreToolUse"
          }
        ]
      }
    ],
    "PostToolUse": [ ... ]
  }
}
```

Claude Code फिर हर टूल कॉल से पहले `failproofai --hook PreToolUse` को एक सबप्रोसेस के रूप में चलाता है, stdin पर एक JSON पेलोड भेजता है।

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

```json theme={null}
{
  "session_id": "abc123",
  "transcript_path": "/home/user/.claude/projects/myproject/sessions/abc123.jsonl",
  "cwd": "/home/user/myproject",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "sudo apt install nodejs" }
}
```

`PostToolUse` इवेंट के लिए, पेलोड में `tool_result` भी होता है जिसमें टूल का आउटपुट होता है।

हैंडलर 1 MB stdin लिमिट लागू करता है। इस सीमा से अधिक पेलोड छोड़ दिए जाते हैं और सभी पॉलिसीज़ निहित रूप से अनुमति देती हैं।

### रेस्पांस प्रारूप

**Deny (PreToolUse):**

```json theme={null}
{
  "hookSpecificOutput": {
    "permissionDecision": "deny",
    "permissionDecisionReason": "Blocked by failproofai: sudo command blocked"
  }
}
```

**Deny (PostToolUse):**

```json theme={null}
{
  "hookSpecificOutput": {
    "additionalContext": "Blocked by failproofai because: API key detected in output"
  }
}
```

**Instruct (किसी भी ईवेंट को छोड़कर Stop):**

```json theme={null}
{
  "hookSpecificOutput": {
    "additionalContext": "Instruction from failproofai: Verify tests pass before committing."
  }
}
```

**Stop event instruct:**

* एक्जिट कोड: `2`
* कारण stderr में लिखा गया (stdout में नहीं)

**Allow:**

* एक्जिट कोड: `0`
* खाली stdout

**संदेश के साथ Allow:**

`allow(message)` एक पॉलिसी को Claude को सूचनात्मक संदर्भ वापस भेजने देता है यहाँ तक कि जब ऑपरेशन की अनुमति हो। हुक हैंडलर निम्नलिखित JSON को **stdout** में लिखता है (एक कॉन्फ़िग फ़ाइल में नहीं — यह हैंडलर का Claude Code को रेस्पांस है, जैसे deny और instruct रेस्पांस के ऊपर):

```json theme={null}
// हुक हैंडलर प्रक्रिया द्वारा stdout में लिखा गया
{
  "hookSpecificOutput": {
    "additionalContext": "All CI checks passed on branch 'feat/my-feature'."
  }
}
```

* एक्जिट कोड: `0` (ऑपरेशन की अनुमति है)
* जब कई पॉलिसीज़ संदेश के साथ `allow` देते हैं, तो उनके संदेश नई पंक्तियों के साथ जुड़ जाते हैं एक एकल `additionalContext` स्ट्रिंग में
* अगर कोई पॉलिसी संदेश प्रदान नहीं करती है, तो stdout खाली है (पहले जैसे)

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

`src/hooks/handler.ts` पूरी पाइपलाइन को लागू करता है:

```text theme={null}
stdin JSON
  → पेलोड को पार्स करें (अधिकतम 1 MB)
  → सेशन मेटाडेटा निकालें (session_id, cwd, tool_name, tool_input, आदि)
  → readMergedHooksConfig(cwd)    ← प्रोजेक्ट + लोकल + ग्लोबल कॉन्फ़िग को मर्ज करता है
  → सक्षम बिल्ट-इन पॉलिसीज़ को हल किए गए पैरामीटर के साथ रजिस्टर करें
  → customPoliciesPath से कस्टम पॉलिसीज़ लोड करें (यदि सेट हो)
  → कस्टम पॉलिसीज़ को पॉलिसी रजिस्ट्री में रजिस्टर करें
  → सभी पॉलिसीज़ का मूल्यांकन करें (पहले बिल्ट-इन्स, फिर कस्टम)
      → पहला deny शॉर्ट-सर्किट करता है
      → instruct निर्णय जमा होते हैं
      → allow संदेश जमा होते हैं
  → stdout में JSON निर्णय लिखें
  → इवेंट को ~/.failproofai/hook-activity.jsonl में रखें
  → एक्जिट करें
```

बिना LLM कॉल के विशिष्ट पेलोड के लिए पूरी प्रक्रिया 100ms में पूरी हो जाती है।

***

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

`src/hooks/hooks-config.ts` तीन-स्कोप कॉन्फ़िग लोडिंग को लागू करता है।

```text theme={null}
[1] {cwd}/.failproofai/policies-config.json        ← प्रोजेक्ट  (सर्वोच्च प्राथमिकता)
[2] {cwd}/.failproofai/policies-config.local.json  ← लोकल
[3] ~/.failproofai/policies-config.json             ← ग्लोबल   (सबसे कम प्राथमिकता)
```

मर्ज लॉजिक:

* `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` दिया गया था, तो deny रेस्पांस उत्सर्जित करें।
* यदि कोई `instruct` रिटर्न एकत्र किए गए हैं, तो सभी संदेशों को जुड़े हुए एकल instruct रेस्पांस उत्सर्जित करें।
* अन्यथा, allow रेस्पांस उत्सर्जित करें (खाली stdout, एक्जिट 0)।

***

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

`src/hooks/builtin-policies.ts` सभी 39 बिल्ट-इन पॉलिसीज़ को `BuiltinPolicyDefinition` ऑब्जेक्ट के रूप में परिभाषित करता है:

```typescript theme={null}
interface BuiltinPolicyDefinition {
  name: string;
  description: string;
  fn: (ctx: PolicyContext) => PolicyResult;
  match: {
    events: HookEventType[];
    tools?: string[];
  };
  defaultEnabled: boolean;
  category: string;
  beta?: boolean;
  params?: PolicyParamsSchema;
}
```

जो पॉलिसीज़ `params` स्वीकार करती हैं वे प्रत्येक पैरामीटर के लिए प्रकार और डिफ़ॉल्ट के साथ `PolicyParamsSchema` की घोषणा करती हैं। पॉलिसी मूल्यांकनकर्ता `fn` को कॉल करने से पहले हल किए गए मानों को `ctx.params` में इंजेक्ट करता है। पॉलिसी फ़ंक्शन `ctx.params` को पढ़ते हैं बिना null-गार्डिंग के क्योंकि डिफ़ॉल्ट हमेशा पहले लागू होते हैं।

पॉलिसीज़ के अंदर पैटर्न मिलान पार्स किए गए कमांड टोकन (argv) का उपयोग करता है, कच्ची स्ट्रिंग मिलान नहीं। यह शेल ऑपरेटर इंजेक्शन के माध्यम से बाईपास को रोकता है (उदाहरण के लिए `sudo systemctl status *` के लिए एक पैटर्न `; rm -rf /` को अपेंड करके बाईपास नहीं किया जा सकता)।

***

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

`src/hooks/custom-hooks-registry.ts` एक `globalThis`-समर्थित रजिस्ट्री को लागू करता है:

```typescript theme={null}
const REGISTRY_KEY = "__failproofai_custom_hooks__";

export const customPolicies = {
  add(hook: CustomHook): void { ... }
};

export function getCustomHooks(): CustomHook[] { ... }
export function clearCustomHooks(): void { ... }  // परीक्षणों में उपयोग किया जाता है
```

`src/hooks/custom-hooks-loader.ts` उपयोगकर्ता की पॉलिसी फ़ाइल लोड करता है:

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

किसी भी त्रुटि पर (फ़ाइल नहीं मिली, syntax त्रुटि, आयात विफलता), त्रुटि को `~/.failproofai/hook.log` में लॉग किया जाता है और लोडर एक खाली सरणी देता है। बिल्ट-इन पॉलिसीज़ प्रभावित नहीं होती हैं।

कस्टम पॉलिसीज़ का मूल्यांकन सभी बिल्ट-इन पॉलिसीज़ के बाद किया जाता है। एक कस्टम पॉलिसी `deny` अभी भी आगे की कस्टम पॉलिसीज़ को शॉर्ट-सर्किट करता है (लेकिन सभी बिल्ट-इन्स पहले ही चल चुकी होती हैं)।

***

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

प्रत्येक हुक ईवेंट के बाद, हैंडलर `~/.failproofai/hook-activity.jsonl` में एक JSONL पंक्ति को अपेंड करता है:

```json theme={null}
{
  "timestamp": "2026-04-06T12:34:56.789Z",
  "sessionId": "abc123",
  "eventType": "PreToolUse",
  "toolName": "Bash",
  "policyName": "block-sudo",
  "decision": "deny",
  "reason": "sudo command blocked by failproofai",
  "durationMs": 12
}
```

एक पंक्ति प्रति पॉलिसी जिसने एक गैर-allow निर्णय दिया। Allow निर्णय लॉग नहीं होते हैं (फ़ाइल को छोटा रखने के लिए)।

***

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

डैशबोर्ड एक **Next.js 16** एप्लिकेशन है जो App Router के साथ React Server Components और Server Actions का उपयोग करता है।

```text theme={null}
app/
  layout.tsx                  ← रूट लेआउट (थीम, टेलीमेट्री, नेव)
  projects/page.tsx           ← सर्वर कंपोनेंट: सभी Claude प्रोजेक्ट सूचीबद्ध करें
  project/[name]/page.tsx     ← सर्वर कंपोनेंट: प्रोजेक्ट में सेशन सूचीबद्ध करें
  project/[name]/session/
    [sessionId]/page.tsx      ← सर्वर कंपोनेंट: सेशन दर्शक रेंडर करें
  policies/page.tsx           ← क्लाइंट कंपोनेंट: पॉलिसी प्रबंधन + गतिविधि लॉग
  actions/
    get-hooks-config.ts       ← कॉन्फ़िग + पॉलिसी सूची पढ़ें
    update-hooks-config.ts    ← पॉलिसी को चालू/बंद करें
    update-policy-params.ts   ← पॉलिसी पैरामीटर अपडेट करें
    get-hook-activity.ts      ← गतिविधि लॉग को पेजिनेट/खोजें
    install-hooks-web.ts      ← ब्राउज़र से हुक्स को इंस्टॉल/हटाएँ
  api/
    download/[project]/[session]/route.ts   ← प्रति-CLI सेशन एक्सपोर्ट (JSONL या JSON)
```

**डेटा प्रवाह:**

* पेज कंपोनेंट प्रोजेक्ट/सेशन डेटा को सीधे फ़ाइलसिस्टम से पढ़ने के लिए `lib/projects.ts` और `lib/log-entries.ts` को कॉल करते हैं (पढ़ने के लिए कोई API परत नहीं)।
* पॉलिसीज़ पेज सभी mutations के लिए Server Actions का उपयोग करता है (टॉगल, params अपडेट, इंस्टॉल/हटाएँ)।
* सेशन दर्शक Claude के JSONL ट्रांसक्रिप्ट प्रारूप को पार्स करता है और संदेशों और टूल कॉल की एक टाइमलाइन रेंडर करता है।

**मुख्य डिज़ाइन निर्णय:**

* कोई डेटाबेस नहीं - सभी स्थायी स्थिति सादे फ़ाइलों में है (`~/.failproofai/`, `~/.claude/projects/`)।
* Mutations के लिए Server Actions - CRUD संचालन के लिए कोई REST API आवश्यक नहीं।
* पढ़ने के पृष्ठों के लिए React Server Components - तेज़ प्रारंभिक लोड, डेटा फ़ेचिंग के लिए कोई क्लाइंट बंडल नहीं।
* क्लाइंट कंपोनेंट केवल जहाँ आवश्यकता हो (पॉलिसी टॉगल, गतिविधि खोज, लॉग दर्शक)।

***

## फ़ाइल लेआउट

```text theme={null}
failproofai/
├── bin/
│   └── failproofai.mjs           # CLI राउटर (hook / dashboard / install / आदि)
├── src/hooks/
│   ├── handler.ts                # हुक ईवेंट पाइपलाइन
│   ├── builtin-policies.ts       # 39 पॉलिसी परिभाषाएं
│   ├── policy-evaluator.ts       # पॉलिसी निष्पादन इंजन
│   ├── policy-registry.ts        # पॉलिसी पंजीकरण और लुकअप
│   ├── policy-types.ts           # TypeScript इंटरफेस
│   ├── hooks-config.ts           # मल्टी-स्कोप कॉन्फ़िग लोडिंग
│   ├── custom-hooks-registry.ts  # globalThis-समर्थित हुक रजिस्ट्री
│   ├── custom-hooks-loader.ts    # उपयोगकर्ता JS हुक्स के लिए ESM लोडर
│   ├── manager.ts                # install / remove / list संचालन
│   ├── install-prompt.ts         # इंटरैक्टिव पॉलिसी चयन प्रॉम्प्ट
│   ├── hook-logger.ts            # hook.log में लॉगिंग
│   ├── hook-activity-store.ts    # hook-activity.jsonl में गतिविधि को रखें
│   └── llm-client.ts             # LLM API क्लाइंट (AI-संचालित पॉलिसीज़ के लिए)
├── app/                          # Next.js डैशबोर्ड (पृष्ठ + Server actions)
├── lib/                          # साझा उपयोगिताएँ
│   ├── projects.ts               # फ़ाइलसिस्टम से Claude प्रोजेक्ट गणना करें
│   ├── log-entries.ts            # Claude ट्रांसक्रिप्ट JSONL प्रारूप को पार्स करें
│   ├── paths.ts                  # सिस्टम पथ हल करें
│   └── ...
├── components/                   # साझा React UI कंपोनेंट
├── contexts/                     # React context प्रदाता (थीम, ऑटो-रीफ्रेश, टेलीमेट्री)
├── examples/                     # उदाहरण कस्टम हुक फ़ाइलें
└── __tests__/                    # यूनिट और E2E परीक्षण
```
