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 giám sát hoạt động của agent.Tổng quan
failproofai có hai hệ thống con độc lập:- Hook handler - Một quy trình CLI nhanh mà Claude Code gọi trên mỗi lệnh gọi công cụ của 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 để giám sát 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 qua hệ thống tệp.
Hook handler
Tích hợp với Claude Code
Khi bạn chạyfailproofai policies --install, nó sẽ ghi các mục như thế này vào ~/.claude/settings.json:
failproofai --hook PreToolUse như một quy trình con trước mỗi lệnh gọi công cụ, truyền một payload JSON vào stdin.
Định dạng payload
PostToolUse, payload cũng chứa tool_result với đầu ra của công cụ.
Handler áp dụng giới hạn stdin 1 MB. Các payload vượt quá giới hạn này 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
Từ chối (PreToolUse):- Mã thoát:
2 - Lý do được ghi vào stderr (không phải stdout)
- Mã thoát:
0 - stdout rỗng
allow(message) cho phép một chính sách gửi bối cảnh thông tin quay 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 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 từ chối và hướng dẫn ở trên):
- Mã thoát:
0(hoạt động được phép) - Khi nhiều chính sách trả về
allowvới một tin nhắn, các tin nhắn của chúng được nối với các 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 tin nhắn, stdout trống (giống như trước đây)
Đường ống xử lý
src/hooks/handler.ts triển khai đầy đủ đường ống:
Tải cấu hình
src/hooks/hooks-config.ts triển khai tải cấu hình ba phạm vi.
enabledPolicies- liên kết không trùng lặp trên cả ba tệppolicyParams- mỗi khóa chính sách, tệp đầu tiên xác định nó sẽ thắng hoàn toàncustomPoliciesPath- 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() (toàn cầu duy nhất) để đọc và ghi, vì nó không được gọi với cwd của dự án.
Đánh giá chính sách
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 nó có). - Đọc
policyParams[policy.name]từ cấu hình đã hợp nhất. - Hợp nhất các giá trị do người dùng cung cấp trên các giá trị mặc định của lược đồ để tạo ra
ctx.params. - Gọi
policy.fn(ctx)với bối cảnh đã được giải quyết. - Nếu kết quả là
deny, dừng 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 đến chính sách tiếp theo.
- Nếu bất kỳ
denynào được trả về, phát ra phản hồi từ chối. - Nếu có bất kỳ phản hồi
instructnào được thu thập, phát ra một phản hồi hướng dẫn duy nhất với tất cả các thông báo được nối lại. - Nếu không, phát ra phản hồi cho phép (stdout trống, thoát 0).
Chính sách tích hợp sẵn
src/hooks/builtin-policies.ts định nghĩa tất cả 39 chính sách tích hợp sẵn dưới dạng các đối tượng BuiltinPolicyDefinition:
params khai báo một PolicyParamsSchema với các kiểu và giá trị mặc định cho mỗi tham số. Người đánh giá chính sách 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 bảo vệ null vì các giá trị mặc định luôn được áp dụng trước.
So khớp mẫu bên trong các chính sách sử dụng các token lệnh được phân tích cú pháp (argv), không phải so khớp chuỗi thô. Điều này ngăn chặn việc vượt qua thông qua tiêm toán tử shell (ví dụ: một mẫu cho sudo systemctl status * không thể bị vượt qua bằng cách nối thêm ; rm -rf / vào lệnh).
Chính sách tùy chỉnh
src/hooks/custom-hooks-registry.ts triển khai một sổ đăng ký đượ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ừ cấu hình; 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ả các mục nhập
from "failproofai"thành đường dẫn dist thực tế đểcustomPoliciesphân giải thành cùng một sổ đăng kýglobalThis. - Viết lại một cách đệ quy các mục nhập cục bộ chuyên qua để đảm bảo khả năng tương thích ESM.
- Ghi các tệp
.mjstạm thời vàimport()tệp entry. - Gọi
getCustomHooks()để lấy các hook đã đăng ký. - Dọn sạch tất cả các tệp tạm thời trong khối
finally.
~/.failproofai/hook.log và loader 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 làm ngắn mạch các chính sách tùy chỉnh tiếp theo (nhưng tất cả các chính sách tích hợp sẵn đã chạy tại thời điểm đó).
Ghi nhật ký hoạt động
Sau mỗi sự kiện hook, handler nối 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 làm việc trực tiếp từ hệ thống tệp (không có lớp API cho các lần đọc). - Trang Policies sử dụng Server Actions cho tất cả các thay đổi (bật/tắt, cập nhật tham số, cài đặt/xóa).
- Trình xem phiên làm việc phân tích định dạng bảng điểm JSONL của Claude và hiển thị dòng thời gian của các thông báo 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 là trong các tệp thô (
~/.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ó gói máy khách cho tìm nạp dữ liệu.
- Các thành phần máy khách chỉ khi cần tương tác (bật/tắt chính sách, tìm kiếm hoạt động, trình xem nhật ký).

