मुख्य सामग्री पर जाएं
कस्टम पॉलिसीज़ आपको किसी भी एजेंट बिहेवियर के लिए नियम लिखने देती हैं: प्रोजेक्ट कन्वेंशन लागू करें, ड्रिफ्ट रोकें, विनाशकारी ऑपरेशन्स को रोकें, फंसे हुए एजेंट्स डिटेक्ट करें, या Slack, अप्रूवल वर्कफ़्लो और अन्य सिस्टम्स के साथ इंटीग्रेट करें। वे बिल्ट-इन पॉलिसीज़ के समान हुक इवेंट सिस्टम और allow, deny, instruct डिसीजन्स का उपयोग करते हैं।

क्विक उदाहरण

// my-policies.js
import { customPolicies, allow, deny, instruct } from "failproofai";

customPolicies.add({
  name: "no-production-writes",
  description: "Block writes to paths containing 'production'",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Write" && ctx.toolName !== "Edit") return allow();
    const path = ctx.toolInput?.file_path ?? "";
    if (path.includes("production")) {
      return deny("Writes to production paths are blocked");
    }
    return allow();
  },
});
इसे इंस्टॉल करें:
failproofai policies --install --custom ./my-policies.js

कस्टम पॉलिसीज़ लोड करने के दो तरीके

विकल्प 1: कन्वेंशन-आधारित (सुझाया गया)

*policies.{js,mjs,ts} फ़ाइलें .failproofai/policies/ में ड्रॉप करें और वे स्वचालित रूप से लोड हो जाती हैं — कोई फ्लैग्स या कॉन्फ़िग बदलाव की जरूरत नहीं। यह git हुक्स की तरह काम करता है: एक फ़ाइल ड्रॉप करें, और यह बस काम करता है।
# प्रोजेक्ट स्तर — git में कमिट किया गया, टीम के साथ साझा किया गया
.failproofai/policies/security-policies.mjs
.failproofai/policies/workflow-policies.mjs

# यूजर स्तर — व्यक्तिगत, सभी प्रोजेक्ट्स पर लागू होता है
~/.failproofai/policies/my-policies.mjs
यह कैसे काम करता है:
  • प्रोजेक्ट और यूजर दोनों डायरेक्टरीज़ स्कैन की जाती हैं (यूनियन — first-scope-wins नहीं)
  • फ़ाइलें प्रत्येक डायरेक्टरी के भीतर वर्णक्रम में लोड होती हैं। ऑर्डर नियंत्रित करने के लिए 01-, 02- प्रीफ़िक्स करें
  • केवल *policies.{js,mjs,ts} से मेल खाने वाली फ़ाइलें लोड होती हैं; अन्य फ़ाइलें अनदेखी की जाती हैं
  • प्रत्येक फ़ाइल स्वतंत्र रूप से लोड होती है (प्रति फ़ाइल fail-open)
  • स्पष्ट --custom और बिल्ट-इन पॉलिसीज़ के साथ काम करता है
कन्वेंशन पॉलिसीज़ आपके ऑर्गनाइज़ेशन के लिए गुणवत्ता स्टैंडर्ड बनाने का सबसे आसान तरीका हैं। .failproofai/policies/ को git में कमिट करें और हर टीम मेंबर को स्वचालित रूप से समान नियम मिलते हैं — कोई प्रति-डेवलपर सेटअप की जरूरत नहीं। जैसे-जैसे आपकी टीम नई विफलता मोड्स खोजती है, एक पॉलिसी जोड़ें और पुश करें। समय के साथ ये एक जीवंत गुणवत्ता स्टैंडर्ड बन जाते हैं जो हर योगदान के साथ बेहतर होते रहते हैं।

विकल्प 2: स्पष्ट फ़ाइल पाथ

# कस्टम पॉलिसीज़ फ़ाइल के साथ इंस्टॉल करें
failproofai policies --install --custom ./my-policies.js

# पॉलिसीज़ फ़ाइल पाथ बदलें
failproofai policies --install --custom ./new-policies.js

# कॉन्फ़िग से कस्टम पॉलिसीज़ पाथ हटाएं
failproofai policies --uninstall --custom
रिज़ॉल्व किया गया निरपेक्ष पाथ policies-config.json में customPoliciesPath के रूप में स्टोर किया जाता है। फ़ाइल हर हुक इवेंट पर ताजा लोड होती है - इवेंट्स के बीच कोई कैशिंग नहीं है।

दोनों को एक साथ उपयोग करना

कन्वेंशन पॉलिसीज़ और स्पष्ट --custom फ़ाइल एक साथ मौजूद रह सकती हैं। लोड ऑर्डर:
  1. स्पष्ट customPoliciesPath फ़ाइल (यदि कॉन्फ़िगर की गई है)
  2. प्रोजेक्ट कन्वेंशन फ़ाइलें ({cwd}/.failproofai/policies/, वर्णक्रम में)
  3. यूजर कन्वेंशन फ़ाइलें (~/.failproofai/policies/, वर्णक्रम में)

API

इम्पोर्ट

import { customPolicies, allow, deny, instruct } from "failproofai";

customPolicies.add(hook)

एक पॉलिसी रजिस्टर करता है। समान फ़ाइल में कई पॉलिसीज़ के लिए आवश्यकतानुसार इसे कॉल करें।
customPolicies.add({
  name: string;                         // आवश्यक - यूनिक आइडेंटिफायर
  description?: string;                 // `failproofai policies` आउटपुट में दिखाया गया
  match?: { events?: HookEventType[] }; // इवेंट टाइप द्वारा फ़िल्टर करें; सभी से मेल खाने के लिए छोड़ दें
  fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
});

डिसीजन हेल्पर्स

फंक्शनप्रभावकब उपयोग करें
allow()ऑपरेशन को चुपचाप अनुमति देंएक्शन सुरक्षित है, कोई संदेश नहीं चाहिए
deny(message)ऑपरेशन को ब्लॉक करेंएजेंट को यह एक्शन नहीं लेना चाहिए
instruct(message)संदर्भ जोड़ें बिना ब्लॉक किएएजेंट को ट्रैक पर रहने के लिए अतिरिक्त संदर्भ दें
deny(message) - संदेश Claude को "Blocked by failproofai:" प्रीफ़िक्स के साथ दिखाई देता है। एक एकल deny सभी आगे के मूल्यांकन को शॉर्ट-सर्किट करता है। instruct(message) - संदेश वर्तमान टूल कॉल के लिए Claude के संदर्भ में जोड़ा जाता है। सभी instruct संदेश जमा किए जाते हैं और एक साथ डिलीवर किए जाते हैं।
आप policyParams में hint फ़ील्ड जोड़कर किसी भी deny या instruct संदेश में अतिरिक्त निर्देश जोड़ सकते हैं — कोई कोड बदलाव की जरूरत नहीं। यह कस्टम (custom/), प्रोजेक्ट कन्वेंशन (.failproofai-project/), और यूजर कन्वेंशन (.failproofai-user/) पॉलिसीज़ के लिए भी काम करता है। विवरण के लिए कॉन्फ़िगरेशन → hint देखें।

सूचनात्मक allow संदेश

allow(message) ऑपरेशन को अनुमति देता है और Claude को वापस एक सूचनात्मक संदेश भेजता है। संदेश हुक हैंडलर के stdout रेस्पांस में additionalContext के रूप में डिलीवर होता है — instruct द्वारा उपयोग किया गया समान तंत्र, लेकिन शब्दार्थ रूप से भिन्न: यह एक स्टेटस अपडेट है, चेतावनी नहीं।
फंक्शनप्रभावकब उपयोग करें
allow(message)अनुमति दें और Claude को संदर्भ भेजेंचेक पास होने की पुष्टि करें, या समझाएं कि चेक क्यों छोड़ा गया
उपयोग मामले:
  • स्टेटस कन्फर्मेशन: allow("All CI checks passed.") — Claude को बताता है सब कुछ ठीक है
  • Fail-open व्याख्याएं: allow("GitHub CLI not installed, skipping CI check.") — Claude को बताता है कि चेक क्यों छोड़ा गया ताकि इसके पास पूर्ण संदर्भ हो
  • कई संदेश जमा होते हैं: यदि कई पॉलिसीज़ में से प्रत्येक allow(message) रिटर्न करता है, तो सभी संदेश नई लाइन्स के साथ जोड़े जाते हैं और एक साथ डिलीवर किए जाते हैं
customPolicies.add({
  name: "confirm-branch-status",
  match: { events: ["Stop"] },
  fn: async (ctx) => {
    const cwd = ctx.session?.cwd;
    if (!cwd) return allow("No working directory, skipping branch check.");

    // ... branch status चेक करें ...
    if (allPushed) {
      return allow("Branch is up to date with remote.");
    }
    return deny("Unpushed changes detected.");
  },
});

PolicyContext फ़ील्ड्स

फ़ील्डटाइपविवरण
eventTypestring"PreToolUse", "PostToolUse", "Notification", "Stop"
toolNamestring | undefinedकॉल किया जा रहा टूल (उदा. "Bash", "Write", "Read")
toolInputRecord<string, unknown> | undefinedटूल के इनपुट पैरामीटर्स
payloadRecord<string, unknown>Claude Code से पूर्ण raw इवेंट पेलोड
sessionSessionMetadata | undefinedसेशन संदर्भ (नीचे देखें)

SessionMetadata फ़ील्ड्स

फ़ील्डटाइपविवरण
sessionIdstringClaude Code सेशन आइडेंटिफायर
cwdstringClaude Code सेशन की वर्किंग डायरेक्टरी
transcriptPathstringसेशन की JSONL ट्रांसक्रिप्ट फ़ाइल का पाथ

इवेंट टाइप्स

इवेंटकब फायर होता हैtoolInput सामग्री
PreToolUseClaude से पहले एक टूल चलाता हैटूल का इनपुट (उदा. Bash के लिए { command: "..." })
PostToolUseएक टूल पूरा होने के बादटूल का इनपुट + tool_result (आउटपुट)
Notificationजब Claude एक नोटिफिकेशन भेजता है{ message: "...", notification_type: "idle" | "permission_prompt" | ... } - हुक्स हमेशा allow() रिटर्न करना चाहिए, वे नोटिफिकेशन्स को ब्लॉक नहीं कर सकते
Stopजब Claude सेशन समाप्त होता हैखाली

मूल्यांकन ऑर्डर

पॉलिसीज़ इस ऑर्डर में मूल्यांकन किए जाते हैं:
  1. बिल्ट-इन पॉलिसीज़ (डेफिनिशन ऑर्डर में)
  2. customPoliciesPath से स्पष्ट कस्टम पॉलिसीज़ (.add() ऑर्डर में)
  3. प्रोजेक्ट .failproofai/policies/ से कन्वेंशन पॉलिसीज़ (फ़ाइलें वर्णक्रम में, .add() ऑर्डर के भीतर)
  4. यूजर ~/.failproofai/policies/ से कन्वेंशन पॉलिसीज़ (फ़ाइलें वर्णक्रम में, .add() ऑर्डर के भीतर)
पहला deny सभी सबसे आगे की पॉलिसीज़ को शॉर्ट-सर्किट करता है। सभी instruct संदेश जमा किए जाते हैं और एक साथ डिलीवर किए जाते हैं।

ट्रांजिटिव इम्पोर्ट्स

कस्टम पॉलिसी फ़ाइलें सापेक्ष पाथ का उपयोग करके स्थानीय मॉड्यूल्स को इम्पोर्ट कर सकती हैं:
// my-policies.js
import { isBlockedPath } from "./utils.js";
import { checkApproval } from "./approval-client.js";

customPolicies.add({
  name: "approval-gate",
  fn: async (ctx) => {
    if (ctx.toolName !== "Bash") return allow();
    const approved = await checkApproval(ctx.toolInput?.command, ctx.session?.sessionId);
    return approved ? allow() : deny("Approval required for this command");
  },
});
एंट्री फ़ाइल से पहुंचने योग्य सभी सापेक्ष इम्पोर्ट्स रिज़ॉल्व किए जाते हैं। यह from "failproofai" इम्पोर्ट्स को वास्तविक dist पाथ में फिर से लिखकर और ESM कम्पैटिबिलिटी सुनिश्चित करने के लिए अस्थायी .mjs फ़ाइलें बनाकर लागू किया जाता है।

इवेंट टाइप फ़िल्टरिंग

match.events का उपयोग करके सीमित करें कि एक पॉलिसी कब फायर हो:
customPolicies.add({
  name: "require-summary-on-stop",
  match: { events: ["Stop"] },
  fn: async (ctx) => {
    // केवल तब फायर होता है जब सेशन समाप्त होता है
    // ctx.session.transcriptPath में पूर्ण सेशन लॉग होता है
    return allow();
  },
});
हर इवेंट टाइप पर फायर करने के लिए match को पूरी तरह छोड़ दें।

एरर हैंडलिंग और विफलता मोड्स

कस्टम पॉलिसीज़ fail-open हैं: एरर्स कभी भी बिल्ट-इन पॉलिसीज़ को ब्लॉक नहीं करते या हुक हैंडलर को क्रैश नहीं करते।
विफलताबिहेवियर
customPoliciesPath सेट नहींकोई स्पष्ट कस्टम पॉलिसीज़ नहीं चलता; कन्वेंशन पॉलिसीज़ और बिल्ट-इन्स सामान्य रूप से जारी रहता है
फ़ाइल नहीं मिली~/.failproofai/hook.log को चेतावनी लॉग की गई; बिल्ट-इन्स जारी रहता है
सिंटैक्स/इम्पोर्ट एरर (स्पष्ट)~/.failproofai/hook.log को एरर लॉग किया गया; स्पष्ट कस्टम पॉलिसीज़ छोड़ दिए गए
सिंटैक्स/इम्पोर्ट एरर (कन्वेंशन)एरर लॉग किया गया; वह फ़ाइल छोड़ दी गई, अन्य कन्वेंशन फ़ाइलें अभी भी लोड होती हैं
fn रनटाइम पर थ्रो करता हैएरर लॉग किया गया; वह हुक allow के रूप में माना जाता है; अन्य हुक्स जारी रहते हैं
fn 10 सेकंड से अधिक समय लेता हैटाइमआउट लॉग किया गया; allow के रूप में माना जाता है
कन्वेंशन डायरेक्टरी गायबकोई कन्वेंशन पॉलिसीज़ नहीं चलता; कोई एरर नहीं
कस्टम पॉलिसी एरर्स को डीबग करने के लिए, लॉग फ़ाइल को देखें:
tail -f ~/.failproofai/hook.log

पूर्ण उदाहरण: कई पॉलिसीज़

// my-policies.js
import { customPolicies, allow, deny, instruct } from "failproofai";

// एजेंट को secrets/ डायरेक्टरी में लिखने से रोकें
customPolicies.add({
  name: "block-secrets-dir",
  description: "Prevent agent from writing to secrets/ directory",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (!["Write", "Edit"].includes(ctx.toolName ?? "")) return allow();
    const path = ctx.toolInput?.file_path ?? "";
    if (path.includes("secrets/")) return deny("Writing to secrets/ is not permitted");
    return allow();
  },
});

// एजेंट को ट्रैक पर रखें: कमिट करने से पहले टेस्ट्स सत्यापित करें
customPolicies.add({
  name: "remind-test-before-commit",
  description: "Keep the agent on track: verify tests pass before committing",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Bash") return allow();
    const cmd = ctx.toolInput?.command ?? "";
    if (/git\s+commit/.test(cmd)) {
      return instruct("Verify all tests pass before committing. Run `bun test` if you haven't already.");
    }
    return allow();
  },
});

// फ्रीज़ अवधि के दौरान अनियोजित डिपेंडेंसी बदलाव रोकें
customPolicies.add({
  name: "dependency-freeze",
  description: "Prevent unplanned dependency changes during freeze period",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Bash") return allow();
    const cmd = ctx.toolInput?.command ?? "";
    const isInstall = /^(npm install|yarn add|bun add|pnpm add)\s+\S/.test(cmd);
    if (isInstall && process.env.DEPENDENCY_FREEZE === "1") {
      return deny("Package installs are frozen. Unset DEPENDENCY_FREEZE to allow.");
    }
    return allow();
  },
});

export { customPolicies };

उदाहरण

examples/ डायरेक्टरी में तैयार-से-चलने वाली पॉलिसी फ़ाइलें हैं:
फ़ाइलसामग्री
examples/policies-basic.jsपांच स्टार्टर पॉलिसीज़ जो सामान्य एजेंट विफलता मोड्स को कवर करती हैं
examples/policies-advanced/index.jsउन्नत पैटर्न्स: ट्रांजिटिव इम्पोर्ट्स, async कॉल्स, आउटपुट स्क्रबिंग, और सेशन-एंड हुक्स
examples/convention-policies/security-policies.mjsकन्वेंशन-आधारित सुरक्षा पॉलिसीज़ (.env राइट्स को ब्लॉक करें, git हिस्ट्री रीराइटिंग को रोकें)
examples/convention-policies/workflow-policies.mjsकन्वेंशन-आधारित वर्कफ़्लो पॉलिसीज़ (टेस्ट रिमाइंडर्स, ऑडिट फ़ाइल राइट्स)

स्पष्ट फ़ाइल उदाहरणों का उपयोग करना

failproofai policies --install --custom ./examples/policies-basic.js

कन्वेंशन-आधारित उदाहरणों का उपयोग करना

# प्रोजेक्ट स्तर पर कॉपी करें
mkdir -p .failproofai/policies
cp examples/convention-policies/*.mjs .failproofai/policies/

# या यूजर स्तर पर कॉपी करें
mkdir -p ~/.failproofai/policies
cp examples/convention-policies/*.mjs ~/.failproofai/policies/
इंस्टॉल कमांड की जरूरत नहीं — अगले हुक इवेंट पर फ़ाइलें स्वचालित रूप से चुन ली जाती हैं।