Quay lại Inside ClaudeKit

Safety & Guard Rails

Guard rails: lớp phanh giữa model và hành động

Guard rail không làm model thông minh hơn — nó kiểm tra hành động trước khi tool thật sự chạy. Bài này mổ xẻ 4 lớp guard, 7 nhóm guard rail và những chỗ vẫn hở trong ClaudeKit.

Case: task nhỏ, quyền quá rộng

Giao agent một việc nhỏ: sửa validation trong một module. Nó quét thêm vài thư mục cho chắc, mở file config nhạy cảm, rồi tiện tay gom vài cleanup không liên quan vào cùng một PR. Test vẫn pass — nhưng context đã lẫn file rác, secret có thể đã vào transcript, review thì loãng.

Không guard rail

  • Glob quá rộng, context bẩn
  • cat .env, secret vào transcript
  • Cleanup ngoài scope, review loãng
  • Test pass nên ship luôn

Có guard rail

  • scout-block exit 2, gợi ý thu hẹp pattern
  • privacy-block exit 2 + hỏi user approval
  • rule / hard-gate kéo về task chính
  • simplify / review gate soi lại diff trước ship

Guard rail vs lời dặn trong prompt

Khía cạnh Guard rail Lời dặn trong prompt
Chạy ở đâu Harness, ngoài model Trong context, model đọc
Ép buộc Code chặn thật (block tool) Model tự nguyện tuân
Khi context dài Vẫn chạy Dễ bị quên / trượt
Khi model hiểu lệch Vẫn chặn (nếu không crash) Lệch theo model
Sửa đổi Cần đụng code/config Sửa text là xong

Hai thứ không loại trừ nhau. Việc rủi ro cao dùng guard rail; việc mang tính phong cách (commit format, comment convention) thì lời dặn là đủ.

4 lớp guard

Hook (code) Chặn thật

Script harness tự gọi tại các mốc lifecycle. Trả exit 2 thì tool KHÔNG chạy. Đây là lớp chặn thật duy nhất.

Nhưng fail-open: hook crash thì Claude Code cho qua, guard tắt âm thầm.

Rule (CLAUDE.md) Lời dặn

Text được inject vào context mỗi prompt. Định hướng hành vi, dễ thêm/sửa, không cần redeploy.

Không có exit 2 nào ép. Model mạnh tuân tốt hơn, prompt user có thể đè.

Hard-gate (XML) Lời dặn mạnh

<HARD-GATE> nằm trong skill markdown, giữ trình tự (code trước plan, ship trước review). Signal mạnh hơn rule thường.

Vẫn là lời dặn, không phải hook. Có dòng "User override".

Guard skill (user gọi) User chủ động

Chạy khi user gõ slash command: /ck:security-scan, /ck:predict, /ck:scenario, /ck:ship.

Không gọi thì không chạy. Là lớp chủ động, không tự động.

Flow một tool call qua guard

1
User prompt Prompt gate (UserPromptSubmit) có thể chặn + nhắc sửa
2
Model quyết định gọi tool Read / Bash / Edit / Write ...
3
Pre-tool hook (scout / privacy) exit 2 → tool KHÔNG chạy, trả lý do về model
4
Tool exec exit 0 → đọc / ghi / chạy thật trên máy
5
Post-tool hook validate, scan, nhắc bước kế (PostToolUse / Stop)
→ Kết quả về model, đã qua các lớp kiểm

Exit code quyết định chặn hay không

exit 0 Cho chạy

Tool chạy bình thường. stdout đọc làm JSON output.

exit 2 Chặn thật

Tool không chạy. Bỏ stdout, đẩy stderr về model làm thông báo lỗi.

exit 1 / khác Lỗi, KHÔNG chặn

Báo lỗi rồi tool VẪN chạy tiếp. Dùng nhầm exit 1 = guard tưởng bật mà thực ra mở.

Chỉ exit 2 mới chặn thật. Hook muốn enforce policy phải dùng đúng exit 2.

7 nhóm guard rail trong CK

Nhóm Cơ chế Ví dụ Ép buộc
Chặn file/path PreToolUse scout-block Code, fail-open
Chặn sai bước UserPromptSubmit simplify-gate Code
Thêm context UserPromptSubmit dev-rules-reminder Code
Giữ tên sạch Pre/Post/Stop descriptive-name Code, nhắc
Hard-gate skill XML markdown <HARD-GATE> Lời dặn
Rule lời dặn CLAUDE.md review-audit Lời dặn
Guard skill User gọi ck:security-scan User

Bốn hook đáng soi kỹ

scout-block

Agent đọc node_modules/, glob **/*.ts ở root, cat dist/ — đốt token, context bẩn.

gap: Build command (npm/go/cargo build) luôn được cho qua. Fail-open khi hook crash.
privacy-block

Agent đụng .env, id_rsa, *.pem — secret lộ vào transcript. Exit 2 + bắt AskUserQuestion.

gap: Bash tool được miễn, chỉ cảnh báo. Pattern secret hard-code, không config thêm được.
simplify-gate

Diff phình > 400 LOC / > 8 file / 1 file > 200 LOC khi prompt có ship/merge/pr/deploy.

gap: Fresh install CHƯA chặn: cần bật simplify.gate.enabled=true. "ship on Friday" cũng bị bỏ qua.
workflow-artifact-gate

Kiểm 5 file JSON (context, risk, verification, review, adversarial) trước ship/push/pr/deploy.

gap: Là gate mạnh nhất nhưng PHẢI opt-in: wire trong settings.json + bật trong .ck.json.

Đọc trạng thái hook theo 3 nhãn

1
script file

File .cjs có nằm trong .claude/hooks/. Có file CHƯA nghĩa là hook đang chạy.

2
wired

settings.json đã gắn script vào lifecycle event. Không wire thì Claude Code không gọi.

3
runtime flag

Khi đã được gọi, code đọc .ck.json / default / ENV để quyết có chạy tiếp không (vd: privacyBlock, simplify.gate.enabled).

isHookEnabled() chỉ tắt khi hooks.<name> là false. Key thiếu thường xem là enabled. Đừng gom mọi thứ thành "mặc định bật/tắt".

8 chỗ vẫn hở (known gaps)

  1. 1 File-access guard nằm ở hook (scout-block / privacy-block), không phải permissions.deny riêng.
  2. 2 Bash được miễn privacy-block — chỉ warn, không qua approval flow.
  3. 3 workflow-artifact-gate cần opt-in. Gate mạnh nhất không chạy nếu chưa bật.
  4. 4 simplify-gate mặc định chưa chặn. Cần bật simplify.gate.enabled rõ ràng.
  5. 5 simplify-gate trượt bằng phrasing — "ship on Friday" được bỏ qua.
  6. 6 .ckignore có thể negate node_modules bằng ! allowlist. Kiểm tra trực tiếp.
  7. 7 Rule là lời dặn — Claude có thể lệch khi prompt user đè.
  8. 8 HARD-GATE XML cũng là lời dặn, có "User override". Không có exit 2 nào ép.

Và: không có rate-limit / quota guard. Agent mất kiểm soát có thể call hàng nghìn Read/Bash; giới hạn nằm ở Claude Code / provider / billing, không ở guard rail.

6 câu kiểm tra trước khi tin guard rail

  • settings.json đang gắn hook nào vào lifecycle nào?
  • .ck.json đã disable hook nào? (cả outer + inner config)
  • Session Claude Code hiện tại có đang bỏ qua permission prompt không?
  • Có project .ckignore override không? node_modules có bị ! allowlist không?
  • Rule files trong CLAUDE.md có đầy đủ không?
  • Có hook nào đang crash âm thầm trong session này không (check stderr)?

Snapshot theo Engineer Kit stable claudekit-engineer@2.19.1. Bản 2.19.2-beta đang chuẩn bị bỏ 2 hook Agent Teams, nên danh sách hook có thể đổi khi upstream release version mới.

Xem chi tiết từng hook trong guide Custom Hooks

Đọc bài viết đầy đủ

Đọc bản đầy đủ với bản đồ ClaudeKit hooks theo lifecycle, snippet settings.json / .ck.json, cơ chế từng hook và phân tích sâu các gap →

Đọc bài viết đầy đủ