דלג לתוכן הראשי

title: ארכיטקטורה description: “כיצד מטפל ה-hook, טעינת התצורה והערכת המדיניות פועלות בפנים” icon: sitemap

מסמך זה מסביר כיצד failproofai פועל בפנים: כיצד מערכת ה-hook מיירטת קריאות כלי סוכן, כיצד תצורה נטענת ומתמזגת, כיצד מדיניות מוערכת, וכיצד לוח הבקרה מעקב אחר פעילות סוכן.

סקירה כללית

ל-failproofai שתי תת-מערכות עצמאיות:
  1. מטפל ה-hook - תהליך CLI מהיר שClaude Code משדר בכל קריאת כלי סוכן. מעריך מדיניות והחזר החלטה.
  2. Agent Monitor (Dashboard) - יישום אינטרנט Next.js לניטור הפעלות סוכן וניהול מדיניות.
שתי תת-המערכות חולקות קבצי תצורה בתיקיות ~/.failproofai/ ו-.failproofai/ של הפרויקט, אך הן פועלות כתהליכים נפרדים ותקשרות רק דרך מערכת הקבצים.

מטפל ה-hook

שילוב עם Claude Code

כאשר אתה מריץ failproofai policies --install, הוא כותב רשומות כמו זו ל-~/.claude/settings.json:
Claude Code לאחר מכן משדר את failproofai --hook PreToolUse כתהליך משנה לפני כל קריאת כלי, תוך העברת מטען JSON על stdin.

פורמט מטען

עבור אירועי PostToolUse, המטען מכיל גם tool_result עם פלט הכלי. המטפל אוכף מגבלת stdin של 1 MB. מטענים החוצים זאת מושלכים והכל מדיניות מרומז כן.

פורמט תגובה

Deny (PreToolUse):
Deny (PostToolUse):
Instruct (כל אירוע מלבד Stop):
Stop event instruct:
  • קוד יציאה: 2
  • סיבה כתובה ל-stderr (לא stdout)
Allow:
  • קוד יציאה: 0
  • stdout ריק
Allow עם הודעה: allow(message) מאפשר למדיניות לשלוח הקשר מידע חזרה ל-Claude גם כאשר הפעולה מותרת. מטפל ה-hook כותב את ה-JSON הבא ל-stdout (לא קובץ תצורה — זהו התגובה של מטפל ה-hook ל-Claude Code, בדיוק כמו תגובות deny ו-instruct לעיל):
  • קוד יציאה: 0 (הפעולה מותרת)
  • כאשר מדיניות מרובות מחזירות allow עם הודעה, ההודעות שלהן מחוברות בשורות חדשות ל-additionalContext בודד
  • אם אין מדיניות המספקת הודעה, stdout ריק (כמו קודם)

צינור עיבוד

src/hooks/handler.ts מיישם את כל הצינור:
כל התהליך רץ תחת 100ms עבור מטענים טיפוסיים ללא קריאות LLM.

טעינת תצורה

src/hooks/hooks-config.ts מיישם טעינת תצורה בתחום שלוש-שלבי.
לוגיקת מיזוג:
  • enabledPolicies - union מפושט בכל שלוש הקבצים
  • policyParams - לכל-מדיניות מפתח, הקובץ הראשון המגדיר אותו מנצח לחלוטין
  • customPoliciesPath - הקובץ הראשון המגדיר אותו מנצח
  • llm - הקובץ הראשון המגדיר אותו מנצח
לוח הבקרה של האינטרנט משתמש ב-readHooksConfig() (global בלבד) לקריאה וכתיבה, מכיוון שהוא לא משודר עם 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 ריק, exit 0).

מדיניות מובנית

src/hooks/builtin-policies.ts מגדיר את כל 39 המדיניות המובנית כאובייקטי BuiltinPolicyDefinition:
מדיניות המקבלת params מכריזה על PolicyParamsSchema עם סוגים וברירות מחדל לכל פרמטר. מעריך המדיניות מוזרק ערכים שנפתרו ל-ctx.params לפני קריאה ל-fn. פונקציות מדיניות קוראות ctx.params ללא הגנת null כי ברירות מחדל תמיד מיושמות קודם. התאמת דפוס בתוך מדיניות משתמשת בעטוקנים של פקודה מנותחים (argv), לא התאמת מחרוזת גולמית. זה מונע עוקף דרך הזרקת אופרטור shell (למשל דפוס עבור sudo systemctl status * לא יכול להיות bypassed על ידי הוספת ; 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() כדי לאחזר hooks שנרשמו.
  7. נקה את כל הקבצים הזמניים בבלוק finally.
בכל שגיאה (קובץ לא נמצא, שגיאת תחביר, כישלון ייבוא), השגיאה מתועדת ל-~/.failproofai/hook.log והמטען מחזיר מערך ריק. מדיניות מובנית אינה מושפעת. מדיניות מותאמת אישית מוערכת לאחר כל המדיניות המובנית. ה-deny של מדיניות מותאמת אישית עדיין מפסיק מדיניות מותאמות אישיות נוספות (אבל כל המובנויות כבר רצו בנקודה זו).

רישום פעילות

לאחר כל אירוע hook, המטפל מוסיף שורת JSONL ל-~/.failproofai/hook-activity.jsonl:
שורה אחת לכל מדיניות שעשתה החלטה שאינה allow. החלטות allow אינן מתועדות (כדי לשמור את הקובץ קטן).

ארכיטקטורה לוח הבקרה

לוח הבקרה הוא יישום Next.js 16 תוך שימוש ב-App Router עם React Server Components ו-Server Actions.
זרימת נתונים:
  • רכיבי עמוד קוראים lib/projects.ts ו-lib/log-entries.ts כדי לקרוא נתוני פרויקט/session ישירות מהמערכת קבצים (אין שכבת API לקריאה).
  • עמוד המדיניות משתמש ב-Server Actions לכל התמורות (toggle, עדכון params, התקנה/הסרה).
  • מסמך ה-session מנתח את פורמט התמלול JSONL של Claude ומעבד ציר זמן של הודעות וקריאות כלי.
החלטות עיצוב מפתח:
  • אין מסד נתונים - כל מצב קבוע נמצא בקבצים רגילים (~/.failproofai/, ~/.claude/projects/).
  • Server Actions למוטציות - אין צורך בAPI REST עבור פעולות CRUD.
  • React Server Components לעמודי קריאה - קריאה ראשונית מהירה יותר, אין חבילת לקוח עבור הביאת נתונים.
  • רכיבי לקוח רק שם צריך אינטראקטיביות (toggles מדיניות, חיפוש פעילות, צופה יומן).

פריסת קובץ