title: Kiến trúc description: “Cách hook handler, config loading, và policy evaluation hoạt động nội bộ” icon: sitemap
Tài liệu này giải thích cách failproofai hoạt động nội bộ: cách hệ thống hook chặn các lệnh gọi công cụ của agent, cách cấu hình được tải và hợp nhất, cách các chính sách được đánh giá, và cách dashboard theo dõi hoạt động của agent.Tổng quan
failproofai có hai hệ thống con độc lập:- Hook handler - Một CLI subprocess nhanh mà Claude Code gọi trên mỗi lệnh gọi công cụ agent. Đánh giá các chính sách và trả về một quyết định.
- Agent Monitor (Dashboard) - Một ứng dụng web Next.js để theo dõi các phiên làm việc của agent và quản lý các chính sách.
~/.failproofai/ và thư mục .failproofai/ của dự án, nhưng chúng chạy dưới dạng các quy trình riêng biệt và chỉ giao tiếp thông qua hệ thống tệp.
Hook handler
Tích hợp với Claude Code
Khi bạn chạyfailproofai policies --install, nó ghi các mục như thế này vào ~/.claude/settings.json:
failproofai --hook PreToolUse như một subprocess trước mỗi lệnh gọi công cụ, truyền một payload JSON trên stdin.
Định dạng payload
PostToolUse, payload cũng chứa tool_result với kết quả của công cụ.
Handler thực thi giới hạn 1 MB cho stdin. Các payload vượt quá giới hạn này sẽ bị loại bỏ và tất cả các chính sách ngầm cho phép.
Định dạng phản hồi
Deny (PreToolUse):- Exit code:
2 - Lý do được ghi vào stderr (không phải stdout)
- Exit code:
0 - stdout trống
allow(message) cho phép một chính sách gửi ngữ cảnh thông tin trở lại Claude ngay cả khi hoạt động được phép. Hook handler ghi JSON sau đây vào stdout (không phải một tệp cấu hình — đây là phản hồi của handler đối với Claude Code, giống như các phản hồi deny và instruct ở trên):
- Exit code:
0(hoạt động được phép) - Khi nhiều chính sách trả về
allowvới một thông báo, các thông báo của chúng được nối với dòng mới thành một chuỗiadditionalContextduy nhất - Nếu không có chính sách nào cung cấp một thông báo, stdout sẽ trống (giống như trước đây)
Pipeline xử lý
src/hooks/handler.ts thực hiện toàn bộ pipeline:
Config loading
src/hooks/hooks-config.ts thực hiện config loading ba phạm vi.
enabledPolicies- hợp nhất được khử trùng lặp trên cả ba tệppolicyParams- mỗi chính sách, tệp đầu tiên xác định nó sẽ thắng toàn bộcustomPoliciesPath- tệp đầu tiên xác định nó sẽ thắngllm- tệp đầu tiên xác định nó sẽ thắng
readHooksConfig() (chỉ toàn cầu) để đọc và ghi, vì nó không được gọi với một project cwd.
Policy evaluation
src/hooks/policy-evaluator.ts chạy các chính sách theo thứ tự.
Đối với mỗi chính sách:
- Tra cứu lược đồ
paramscủa chính sách (nếu có). - Đọc
policyParams[policy.name]từ config đã hợp nhất. - Hợp nhất các giá trị do người dùng cung cấp vào các giá trị mặc định của lược đồ để tạo
ctx.params. - Gọi
policy.fn(ctx)với ngữ cảnh đã được giải quyết. - Nếu kết quả là
deny, dừng lại ngay lập tức và trả về quyết định đó. - Nếu kết quả là
instruct, tích lũy thông báo và tiếp tục. - Nếu kết quả là
allow, tiếp tục với chính sách tiếp theo.
- Nếu bất kỳ
denynào được trả về, phát hành phản hồi deny. - Nếu bất kỳ kết quả
instructnào được thu thập, phát hành một phản hồi instruct duy nhất với tất cả các thông báo được nối. - Ngoài ra, phát hành phản hồi allow (stdout trống, exit 0).
Builtin policies
src/hooks/builtin-policies.ts định nghĩa tất cả 39 chính sách tích hợp sẵn như các đối tượng BuiltinPolicyDefinition:
params khai báo PolicyParamsSchema với các loại và giá trị mặc định cho mỗi tham số. Policy evaluator tiêm các giá trị đã được giải quyết vào ctx.params trước khi gọi fn. Các hàm chính sách đọc ctx.params mà không cần null-guarding vì các giá trị mặc định luôn được áp dụng trước.
Pattern matching bên trong các chính sách sử dụng các token lệnh được phân tích (argv), không phải so khớp chuỗi thô. Điều này ngăn chặn bypass thông qua shell operator injection (ví dụ: một mẫu cho sudo systemctl status * không thể bị bypass bằng cách thêm ; rm -rf / vào lệnh).
Custom policies
src/hooks/custom-hooks-registry.ts thực hiện một registry được hỗ trợ bởi globalThis:
src/hooks/custom-hooks-loader.ts tải tệp chính sách của người dùng:
- Đọc
customPoliciesPathtừ config; bỏ qua nếu không có. - Giải quyết đến đường dẫn tuyệt đối; kiểm tra tệp tồn tại.
- Viết lại tất cả
from "failproofai"imports đến đường dẫn dist thực tế đểcustomPoliciesgiải quyết đến cùng một registryglobalThis. - Viết lại một cách đệ quy các import local chuyên cần để đảm bảo tương thích ESM.
- Ghi các tệp
.mjstạm thời vàimport()tệp mục nhập. - Gọi
getCustomHooks()để truy xuất các hook đã đăng ký. - Dọn dẹp tất cả các tệp tạm thời trong một khối
finally.
~/.failproofai/hook.log và loader sẽ trả về một mảng trống. Các chính sách tích hợp sẵn không bị ảnh hưởng.
Các chính sách tùy chỉnh được đánh giá sau tất cả các chính sách tích hợp sẵn. Một chính sách tùy chỉnh deny vẫn ngắn mạch các chính sách tùy chỉnh tiếp theo (nhưng tất cả các builtins đã chạy ở thời điểm này).
Activity logging
Sau mỗi sự kiện hook, handler thêm một dòng JSONL vào~/.failproofai/hook-activity.jsonl:
Kiến trúc Dashboard
Dashboard là một ứng dụng Next.js 16 sử dụng App Router với React Server Components và Server Actions.- Các thành phần trang gọi
lib/projects.tsvàlib/log-entries.tsđể đọc dữ liệu dự án/phiên trực tiếp từ hệ thống tệp (không có lớp API để đọc). - Trang Policies sử dụng Server Actions cho tất cả các thay đổi (toggle, cập nhật params, install/remove).
- Trình xem phiên phân tích định dạng transcript JSONL của Claude và hiển thị một dòng thời gian của các tin nhắn và lệnh gọi công cụ.
- Không có cơ sở dữ liệu - tất cả trạng thái liên tục nằm trong các tệp thuần (
~/.failproofai/,~/.claude/projects/). - Server Actions cho các thay đổi - không cần REST API cho các hoạt động CRUD.
- React Server Components cho các trang đọc - tải ban đầu nhanh hơn, không có client bundle cho việc tìm nạp dữ liệu.
- Các thành phần client chỉ khi cần tương tác (toggles chính sách, tìm kiếm hoạt động, trình xem nhật ký).

