الانتقال إلى المحتوى الرئيسي

title: التكوين description: “تنسيق ملف الإعدادات، نظام النطاقات الثلاثة، وقواعد الدمج” icon: gear

يستخدم failproofai ملفات تكوين JSON للتحكم في السياسات النشطة وسلوكها وموقع تحميل السياسات المخصصة. تم تصميم التكوين ليكون سهل المشاركة مع فريقك - قم بإرساله إلى مستودع المشروع وسيحصل كل مطور على نفس شبكة الأمان للوكيل.

نطاقات التكوين

هناك ثلاثة نطاقات تكوين، يتم تقييمها بترتيب الأولوية:
النطاقمسار الملفالغرض
المشروع.failproofai/policies-config.jsonإعدادات لكل مستودع، مرسلة للتحكم بالإصدار
محلي.failproofai/policies-config.local.jsonتجاوزات شخصية لكل مستودع، مُضافة لـ gitignore
عام~/.failproofai/policies-config.jsonالإعدادات الافتراضية على مستوى المستخدم عبر جميع المشاريع
عندما يتلقى failproofai حدث hook، يقوم بتحميل ودمج جميع الملفات الثلاثة الموجودة للمجلد الحالي.

قواعد الدمج

enabledPolicies - اتحاد جميع النطاقات الثلاثة. السياسة المفعلة في أي مستوى تكون نشطة.
project:  ["block-sudo"]
local:    ["block-rm-rf"]
global:   ["block-sudo", "sanitize-api-keys"]

resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"]  ← اتحاد مع إزالة التكرار
policyParams - النطاق الأول الذي يحدد معاملات السياسة يفوز بالكامل. لا يوجد دمج عميق للقيم داخل معاملات السياسة.
project:  block-sudo → { allowPatterns: ["sudo apt-get update"] }
global:   block-sudo → { allowPatterns: ["sudo systemctl status"] }

resolved: { allowPatterns: ["sudo apt-get update"] }   ← المشروع يفوز، يتم تجاهل global
project:  (no block-sudo entry)
local:    (no block-sudo entry)
global:   block-sudo → { allowPatterns: ["sudo systemctl status"] }

resolved: { allowPatterns: ["sudo systemctl status"] }  ← الانتقال إلى global
customPoliciesPath - النطاق الأول الذي يحدده يفوز. llm - النطاق الأول الذي يحدده يفوز.

تنسيق ملف الإعدادات

{
  "enabledPolicies": [
    "block-sudo",
    "block-rm-rf",
    "block-push-master",
    "sanitize-api-keys",
    "sanitize-jwt",
    "block-env-files",
    "block-read-outside-cwd"
  ],
  "policyParams": {
    "block-sudo": {
      "allowPatterns": ["sudo systemctl status", "sudo journalctl"]
    },
    "block-push-master": {
      "protectedBranches": ["main", "release", "prod"]
    },
    "block-rm-rf": {
      "allowPaths": ["/tmp"]
    },
    "block-read-outside-cwd": {
      "allowPaths": ["/shared/data", "/opt/company"]
    },
    "sanitize-api-keys": {
      "additionalPatterns": [
        { "regex": "myco_[A-Za-z0-9]{32}", "label": "MyCo API key" }
      ]
    },
    "warn-large-file-write": {
      "thresholdKb": 512
    }
  },
  "customPoliciesPath": "/home/alice/myproject/my-policies.js"
}

مرجع الحقول

enabledPolicies

النوع: string[] قائمة بأسماء السياسات المراد تفعيلها. يجب أن تطابق الأسماء بالضبط معرّفات السياسة التي يعرضها failproofai policies. انظر السياسات المدمجة للحصول على القائمة الكاملة. السياسات غير الموجودة في enabledPolicies غير نشطة، حتى لو كانت لديها إدخالات في policyParams.

policyParams

النوع: Record<string, Record<string, unknown>> تجاوزات معاملات كل سياسة. المفتاح الخارجي هو اسم السياسة؛ المفاتيح الداخلية خاصة بكل سياسة. توثق كل سياسة المعاملات المتاحة لديها في السياسات المدمجة. إذا كانت السياسة تحتوي على معاملات ولم تحددها، يتم استخدام القيم الافتراضية المدمجة للسياسة. المستخدمون الذين لا يقومون بتكوين policyParams على الإطلاق سيحصلون على سلوك متطابق مع الإصدارات السابقة. المفاتيح المجهولة داخل كتلة معاملات السياسة يتم تجاهلها بصمت في وقت تشغيل hook لكن يتم وضع علامة عليها كتحذيرات عند تشغيل failproofai policies.

hint (العام)

النوع: string (اختياري) رسالة يتم إلحاقها بالسبب عندما تُرجع السياسة deny أو instruct. استخدمه لإعطاء Claude إرشادات قابلة للتنفيذ دون تعديل السياسة نفسها. يعمل مع أي نوع سياسة - مدمج، مخصص (custom/)، اتفاقية المشروع (.failproofai-project/)، أو اتفاقية المستخدم (.failproofai-user/).
{
  "policyParams": {
    "block-force-push": {
      "hint": "حاول إنشاء فرع طازج بدلاً من ذلك."
    },
    "block-sudo": {
      "allowPatterns": ["sudo apt-get"],
      "hint": "استخدم apt-get مباشرة بدون sudo."
    },
    "custom/my-policy": {
      "hint": "اطلب موافقة المستخدم أولاً."
    }
  }
}
عندما يقوم block-force-push برفض، يرى Claude: “دفع القوة مُحظور. حاول إنشاء فرع طازج بدلاً من ذلك.” القيم غير النصية والنصوص الفارغة يتم تجاهلها بصمت. إذا لم يتم تعيين hint، يبقى السلوك بدون تغيير (متوافق للخلف).

customPoliciesPath

النوع: string (مسار مطلق) مسار ملف JavaScript يحتوي على سياسات hook مخصصة. يتم تعيينه تلقائياً بواسطة failproofai policies --install --custom <path> (يتم حل المسار إلى مطلق قبل تخزينه). يتم تحميل الملف بشكل جديد في كل حدث hook - لا يوجد تخزين مؤقت. انظر السياسات المخصصة لتفاصيل التأليف.

سياسات قائمة على الاتفاقيات

بالإضافة إلى customPoliciesPath الصريح، يقوم failproofai بالكشف التلقائي وتحميل ملفات السياسة من مجلدات .failproofai/policies/:
المستوىالمجلدالنطاق
المشروع.failproofai/policies/مشترك مع الفريق عبر التحكم بالإصدار
المستخدم~/.failproofai/policies/شخصي، ينطبق على جميع المشاريع
مطابقة الملفات: يتم تحميل الملفات فقط التي تطابق *policies.{js,mjs,ts} (على سبيل المثال security-policies.mjs, workflow-policies.js). يتم تجاهل الملفات الأخرى في المجلد. لا يلزم التكوين: سياسات الاتفاقيات لا تتطلب إدخالات في policies-config.json. قم فقط بإسقاط الملفات في المجلد وسيتم التقاطها في حدث hook التالي. تحميل الاتحاد: يتم مسح كل من مجلدات الاتفاقيات للمشروع والمستخدم. يتم تحميل جميع الملفات المطابقة من كلا المستويين (بخلاف customPoliciesPath الذي يستخدم أولوية النطاق الأول). انظر السياسات المخصصة لمزيد من التفاصيل والأمثلة.

llm

النوع: object (اختياري) تكوين عميل LLM للسياسات التي تجري استدعاءات AI. غير مطلوب لمعظم الإعدادات.
{
  "llm": {
    "model": "claude-sonnet-4-6",
    "apiKey": "sk-ant-..."
  }
}

إدارة التكوين من سطر الأوامر

تقوم أوامر policies --install و policies --uninstall بالكتابة إلى ملف إعدادات hook الخاص بـ agent CLI (نقاط دخول hook)، بينما policies-config.json هو الملف الذي تديره مباشرة. الاثنان منفصلان:
  • إعدادات Agent CLI — يخبر الوكيل باستدعاء failproofai --hook <event> في كل استخدام أداة:
    • Claude Code: ~/.claude/settings.json (مستخدم)، <cwd>/.claude/settings.json (مشروع)، <cwd>/.claude/settings.local.json (محلي)
    • OpenAI Codex: ~/.codex/hooks.json (مستخدم)، <cwd>/.codex/hooks.json (مشروع) — Codex لا يحتوي على نطاق local
    • GitHub Copilot CLI (beta): ~/.copilot/hooks/failproofai.json (مستخدم)، <cwd>/.github/hooks/failproofai.json (مشروع) — Copilot لا يحتوي على نطاق local. إدخالات Hook تستخدم حقول أوامر Copilot المفتاحية للنظام التشغيلي bash/powershell مع timeoutSec؛ يحمل الملف علامة version: 1 على المستوى الأعلى. دعم Copilot CLI في beta بينما نتحقق من مخطط سجل events.jsonl (الذي لا توفره الوثائق العامة) مقابل جلسات حقيقية أكثر.
    • Cursor Agent (beta): ~/.cursor/hooks.json (مستخدم)، <cwd>/.cursor/hooks.json (مشروع) — Cursor لا يحتوي على نطاق local. إدخالات Hook تستخدم نموذج Claude {type, command, timeout} (بدون تقسيم bash/powershell)، لكن مخزنة تحت مفاتيح الأحداث بـ camelCase (preToolUse, beforeSubmitPrompt, …) في مصفوفة مسطحة وفقاً لـ مخطط hooks الخاص بـ Cursor؛ يحمل الملف علامة version: 1 على المستوى الأعلى. يقوم المعالج بتشريع camelCase → PascalCase عبر CURSOR_EVENT_MAP بحيث تطلق السياسات المدمجة الموجودة بدون تغيير. دعم Cursor Agent في beta بينما نتحقق من نص Cursor على القرص (غير محدد في الوثائق العامة) مقابل تثبيتات حقيقية أكثر.
    • OpenCode (beta): ~/.config/opencode/opencode.json + ~/.config/opencode/plugins/failproofai.mjs (مستخدم)، <cwd>/.opencode/opencode.json + <cwd>/.opencode/plugins/failproofai.mjs (مشروع) — OpenCode لا يحتوي على نطاق local. بخلاف CLI الستة الأخرى، OpenCode ليس لديه نظام hook أوامر خارجية: يقوم بتحميل مكونات JS/TS في العملية والمسجلة بشكل صريح عبر مصفوفة plugin: [] في opencode.json (الاكتشاف التلقائي من .opencode/plugins/ ليس كيفية تحميل المكونات الإضافية على opencode v1.14.33). يسقط التثبيت shim مكون إضافي صغير مُولّد يستدعي ثنائي failproofai بـ subprocess ويترجم استجابة JSON على شكل Claude للثنائي مرة أخرى إلى دلالات المكون الإضافي: throw new Error() لأداة-حدث deny (يلغي استدعاء الأداة)، client.session.prompt(...) لـ instruct و Stop / SubagentStop deny (يرسل سبب الرفض كرسالة المستخدم التالية — قناة إعادة المحاولة الوحيدة لأن session.idle هي إشعار فقط والرمي منها هو no-op)، و no-op للسماح. يقوم Shim بتشريع أسماء الأدوات (lowercase → PascalCase عبر OPENCODE_TOOL_MAP) ومفاتيح إدخال الأداة (camelCase → snake_case عبر OPENCODE_TOOL_INPUT_MAP لـ Read / Write / Edit، على سبيل المثال filePathfile_path, oldStringold_string) قبل الإرسال إلى الثنائي، بحيث يطلق التحقق من المسار المدمج مثل block-read-outside-cwd, block-env-files, و block-secrets-write بدون تغيير على استدعاءات أدوات OpenCode. تعيش الجلسات في SQLite DB الخاص بـ opencode على ~/.local/share/opencode/opencode.db؛ عارض الجلسات للوحة المعلومات يقرأها عبر opencode db --format json و opencode export <id>. دعم OpenCode في beta بينما نتحقق من السلوك عبر الإصدارات ومقابل جلسات حقيقية أكثر. انظر وثائق مكونات OpenCode.
    • Pi (beta): ~/.pi/agent/settings.json (مستخدم)، <cwd>/.pi/settings.json (مشروع) — Pi لا يحتوي على نطاق local. يقوم Pi بتحميل حزم ملحقات TypeScript عند البدء؛ ملف الإعدادات هو مصفوفة سلسلة مسطحة {"packages": ["./relative/path", …]}. يكتب failproofai إدخال مصفوفة حزم واحد يشير إلى مجلد pi-extension/ المجمع الخاص به. يشترك الملحق داخلياً في أحداث Pi tool_call / user_bash / input / session_start ويستدعي failproofai --hook <Event> --cli pi؛ يقوم المعالج بتشريع underscore_lower_snake_case → PascalCase عبر PI_EVENT_MAP بحيث تطلق السياسات المدمجة الموجودة بدون تغيير. تتم مراجعة معاملات إدخال الأداة أيضاً عبر PI_TOOL_INPUT_MAP (Pi’s Read / Write / Edit تسلم path بدلاً من file_path؛ تعيين المفتاح على المستوى الأعلى يسمح لـ block-env-files و block-secrets-write بالتطبيق — block-read-outside-cwd كان بالفعل لديه احتياطي path). دعم Pi في beta بينما تستقر API ملحق Pi ومخطط سجل الجلسة.
    • Gemini CLI (beta): ~/.gemini/settings.json (مستخدم)، <cwd>/.gemini/settings.json (مشروع) — Gemini لا يحتوي على نطاق local (يوثق نطاق system في /etc/gemini-cli/settings.json الذي لا يعرضه failproofai). إدخالات Hook تستخدم نموذج Claude {type, command, timeout} ملفوف في مخطط matcher Gemini {matcher, hooks: [...]} مع matcher: "*" بشكل افتراضي. الأحداث بـ PascalCase (SessionStart, BeforeAgent, AfterAgent, BeforeModel, AfterModel, BeforeToolSelection, BeforeTool, AfterTool, PreCompress, Notification, SessionEnd)؛ يقوم المعالج بالتعيين إلى أسماء Claude الأساسية عبر GEMINI_EVENT_MAP. أسماء الأدوات بـ snake_case (run_shell_command, read_file, write_file, replace, …) — يقوم المعالج بالتشريع عبر GEMINI_TOOL_MAP بحيث تطلق السياسات المدمجة الموجودة بدون تغيير. يصدر محقق السياسة نموذج Gemini المسطح {decision: "deny", reason} (المفضل وفقاً لقاعدة Gemini الذهبية exit-0)، {hookSpecificOutput: {hookEventName, additionalContext}} لحقن السياق في BeforeAgent / AfterTool / SessionStart، و {decision: "block", reason} في AfterAgent لدلالات إعادة المحاولة الإجبارية. دعم Gemini CLI في beta بينما نوسع التغطية الحقيقية. انظر وثائق hooks Gemini CLI.
  • policies-config.json — يخبر failproofai بالسياسات المراد تقييمها والمعاملات التي تستخدمها (مشترك عبر جميع CLI الوكيل)
مرر --cli claude|codex|copilot|cursor|opencode|pi|gemini لاستهداف وكيل معين (مفصول بمسافات أو متكرر لأي مجموعة فرعية):
failproofai policies --install --cli codex --scope project
failproofai policies --install --cli copilot --scope project
failproofai policies --install --cli cursor --scope project
failproofai policies --install --cli opencode --scope project
failproofai policies --install --cli pi --scope project
failproofai policies --install --cli gemini --scope project
failproofai policies --install --cli claude codex copilot cursor opencode pi gemini
عند حذف --cli، يكتشف failproofai أي CLI وكيل مثبت (which claude / which codex / which copilot / which cursor-agent / which opencode / which pi / which gemini):
  • يتم الكشف عن CLI واحد — يختار تلك CLI تلقائياً بدون مطالبة.
  • يتم الكشف عن عدة CLI في جهاز طرفي تفاعلي — يعرض موجه اختيار واحد مع مفاتيح الأسهم معروض بمجموعات في قسم Detected (N) (مع صف إجمالي Install for all N detected + كل CLI يتم الكشف عنها بشكل فردي) وقسم Not installed (M) · install hooks ahead of time يسرد كل CLI مدعومة لم يتم اكتشافها كخيار تثبيت مسبق (↑↓ للتحرك، Enter للتحديد، ^C للخروج). يعرض تدفق الإلغاء القسم المكتشف فقط.
  • يتم الكشف عن عدة CLI في تشغيل غير تفاعلي (CI، بدون TTY) — يثبت لجميع CLI المكتشفة بدون مطالبة.
  • لم يتم الكشف عن أي — يرجع إلى claude، مع تحذير من أن لم يتم العثور على ثنائي وكيل في PATH؛ أمر hook لا يزال مكتوباً بحيث ينشط بمجرد تثبيت واحد.
يمكنك تحرير policies-config.json مباشرة في أي وقت؛ تصبح التغييرات فعالة فوراً في حدث hook التالي بدون الحاجة إلى إعادة تشغيل.

مثال: تكوين على مستوى المشروع مع قيم افتراضية الفريق

قم بإرسال .failproofai/policies-config.json إلى المستودع:
{
  "enabledPolicies": [
    "block-sudo",
    "block-rm-rf",
    "block-push-master",
    "sanitize-api-keys",
    "block-env-files"
  ],
  "policyParams": {
    "block-push-master": {
      "protectedBranches": ["main", "release", "hotfix"]
    }
  }
}
يمكن لكل مطور بعد ذلك إنشاء .failproofai/policies-config.local.json (مضاف لـ gitignore) للتجاوزات الشخصية دون التأثير على زملاء الفريق.