Guard rails: lớp phanh giữa model và hành động
ENGuard rails: the brake layer between model and action · Đọc bản tiếng Anh
Khi agent có quyền đọc file, chạy shell, sửa code và ship PR, một dòng dặn trong prompt là chưa đủ. Cần một lớp kiểm tra trước khi tool thật sự chạy.
Inside ClaudeKit · Guard rails deep dives
Khi agent có quyền đọc file, chạy shell, sửa code và ship PR, một dòng dặn trong prompt là chưa đủ. Cần một lớp kiểm tra trước khi tool thật sự chạy.
4 - lớp guard · 7 - nhóm guard rail · 2 - lớp config · 8 - gap đã biết · 13 - section
Case
Một task nhỏ, nhiều quyền quá rộng
Bạn giao cho agent một việc nhỏ: sửa validation trong một module. Nó muốn chắc hơn nên quét thêm vài thư mục, mở file config nhạy cảm, rồi tiện tay gom luôn vài cleanup không liên quan vào cùng một PR.
Nhìn qua thì mọi thứ vẫn ổn. Test vẫn pass. Nhưng context đã lẫn file rác, secret có thể đã đi vào transcript (toàn bộ bản ghi hội thoại giữa bạn và agent), còn review thì bị loãng vì phần cần sửa và phần "tiện tay" nằm chung một PR.
Không guard rail
- Glob quá rộng — context bẩn
cat .env— secret vào transcript- Cleanup ngoài scope — review bị loãng
- Test pass nên làm tiếp — thiếu bước kiểm tra scope
Có guard rail
- Glob rộng — scout-block exit 2
.env— privacy-block hỏi user- Scope lệch — rule/hard-gate nhắc quay lại task chính
- Trước khi ship — simplify/review gate kiểm tra lại diff
Agent không tự nhiên cẩn thận hơn. Chỉ là trước khi nó làm gì đó, có một lớp đứng ra hỏi: việc này có nên được phép chạy không?
Ý chính
Hook là lớp chặn thật.
Guard rail không làm model thông minh hơn. Nó kiểm tra hành động trước khi tool chạy. Rule, hard-gate và guard skill là các lớp định hướng thêm, hữu ích nhưng vẫn phụ thuộc model hoặc user có gọi hay không.
I. Khái niệm
Guard rail là gì trong agentic coding
Guard rail là lớp đứng giữa agent và hành động: việc rủi ro thì chặn, việc đáng nghi thì cảnh báo. Nó giống lan can ở mép cầu thang: không làm bạn đi giỏi hơn, nhưng giảm khả năng một cú bước hụt thành tai nạn. Khác với lời dặn trong prompt, tức prompt instruction, guard rail chạy ở tầng điều phối tool, không phụ thuộc model có "nhớ" hay không.
Phân biệt guard rail và lời dặn
| Guard rail | Lời dặn | |
|---|---|---|
| Chạy ở đâu | Harness, ngoài model | Trong context, model đọc |
| Ép buộc | Code chặn thật | Model tự nguyện tuân |
| Context dài | Vẫn chạy | Dễ quên / trượt |
| Model hiểu lệch | Vẫn chặn (nếu không crash) | Lệch theo model |
| Sửa đổi | Đụng code/config | Sửa text là xong |
Guard rail hoạt động thế nào
Harness là lớp runtime bọc quanh model. Model chỉ quyết định "tôi muốn đọc file này" hoặc "tôi muốn chạy lệnh này"; harness mới là bên nhận tool call, quản quyền, gọi hook, cho tool chạy hoặc chặn, rồi trả kết quả lại cho model. Hook là script nhỏ harness tự gọi tại các thời điểm cố định trong vòng đời một tool call — lúc nhận prompt, trước tool, sau tool — để xen vào kiểm tra. Vì mọi hành động thật đều qua harness, đây là chỗ gắn guard rail.
Đọc thêm nền khái niệm: Harness Engineering là gì? của Duy /zuey/.
Bản đồ ClaudeKit Hooks
Chi tiết ClaudeKit Hooks có thể xem thêm tại VividKit Guides.
Hook không nằm trong model. Nó nằm ở lifecycle của Claude Code: settings.json quyết định hook nào được gọi, .ck.json/ENV quyết định runtime behavior, còn output của hook có thể cho chạy, chặn, inject context hoặc ghi state/artifact sau khi tool hoặc session kết thúc.
Flow một tool call qua guard rail
Điểm mấu chốt: pre-tool hook trả exit code. Exit 0 cho tool chạy, exit 2 chặn và đẩy lý do về model. Ba điểm chèn chính trong flow có tên kỹ thuật tương ứng: UserPromptSubmit (lúc nhận prompt), PreToolUse (trước tool), PostToolUse (sau tool). Riêng Stop/SubagentStop chạy khi session hoặc subagent kết thúc, nên nằm ở bản đồ lifecycle phía trên.
Exit code nghĩa là gì
Exit code là số process trả về khi kết thúc. Claude Code đọc nó để quyết tool có chạy không:
exit 0— OK, tool chạy. stdout đọc làm JSON output.exit 2— chặn. Bỏ stdout, đẩy stderr về model làm thông báo lỗi.exit 1(hoặc mã khác) — lỗi nhưng KHÔNG chặn. Báo lỗi rồi tool vẫn chạy tiếp.
Chỉ exit 2 mới chặn thật. Hook muốn enforce policy phải dùng đúng exit 2 — dùng nhầm exit 1 theo thói quen Unix là guard tưởng bật mà thực ra mở.
Hai kiểu chặn
Hard · code
Hook exit 2, tool không chạy. Nhưng hook crash → Claude Code cho qua (fail-open). Bug ở hook làm guard tắt âm thầm.
Soft · text
Thêm text vào context (rule, hard-gate). Model phải tự tuân. Mạnh hay yếu phụ thuộc model.
Lợi ích
- Giữ context sạch · giữ secret khỏi transcript
- Giữ nhịp: plan → simplify → review
- Chặn sớm trước khi rủi ro lan ra — agent định đọc
.env, quét quá rộng, hoặc kéo cleanup ngoài scope vào PR - Nhiều lớp bù nhau — hook có thể fail-open, rule có thể bị model bỏ qua, guard skill có thể không được gọi; tách thành nhiều lớp giúp giảm phụ thuộc vào một điểm chặn duy nhất
II\. Hiện thực trong CK
Bảy nhóm guard rail trong CK
Lưu ý quan trọng
Sau một fresh CK install, file-access guard nằm ở PreToolUse hook như scout-block và privacy-block. Nếu phiên Claude Code đang chạy ở mode bỏ qua permission prompt, các hook này vẫn là lớp chặn chính của CK. Nhưng hook CK là fail-open: crash hoặc bị disable thì tool call có thể đi tiếp.
| 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 |
Nhóm nào đọc ở đâu
Chặn file/path - scout-block, privacy-block · Section 05-06 · Chặn sai bước - simplify-gate, workflow gate · Section 07-08 · Thêm context - dev-rules-reminder inject text vào prompt · Section 10 · Giữ tên sạch - descriptive-name · hook grid trong Section 04 · Hard-gate skill - <HARD-GATE> · Section 09 · Rule lời dặn - CLAUDE.md rules là nội dung được inject · Section 10 · Guard skill - ck:security-scan, ck:ship · Section 11
9 tình huống quen thuộc
| Tình huống | Lớp xử lý |
|---|---|
Đọc node_modules/react/ | scout-block, exit 2 |
Đọc .env check key | privacy-block, exit 2 + approval prompt |
Glob **/*.ts ở root | scout-block broad-pattern |
| Prompt ship khi diff đã phình to | simplify-gate, nếu gate.enabled=true |
| Bắt đầu code khi chưa có plan/review | ck:cook HARD-GATE |
| Đổi threshold user đã chốt | review-audit rule: hỏi lại trước khi đổi |
| File mới tên mơ hồ | descriptive-name, PreToolUse(Write) |
| Plan dùng link/text sai format | plan-format-kanban, PostToolUse(Edit/Write/MultiEdit) |
| Hai teammate đụng cùng file | team-coordination rule, chỉ trong Agent Team |
Bản đồ config · nơi kiểm hook có thật sự chạy không
Settings và các lớp config
Hai lớp config quyết định guard nào chạy: settings.json gắn hook vào lifecycle của Claude Code; .ck.json bật/tắt từng hook và chỉnh threshold.
# Global scope
~/.claude/settings.json
~/.claude/.ck.json
~/.claude/hooks/*.cjs# Project scope
.claude/settings.json
.claude/.ck.json
.claude/hooks/*.cjssettings.json: hook nào chạy ở mốc nào
Snippet dưới đây chỉ minh hoạ một lát cắt PreToolUse trong fresh CK install: CK cung cấp scout-block và privacy-block, rồi wire chúng vào lifecycle để Claude Code gọi trước khi tool chạy. Full hook config trên máy đã cài còn nhiều lifecycle event hơn; nơi cần xem là settings.json của Claude Code.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Glob|Grep|Read|Edit|Write",
"hooks": [
{ "command": "node \".claude/hooks/scout-block.cjs\"" },
{ "command": "node \".claude/hooks/privacy-block.cjs\"" }
]
}
]
}
}settings.json là bản đồ lifecycle: khi user gửi prompt thì hook nào chạy, trước khi tool chạy thì hook nào được gọi, sau khi tool xong thì hook nào xử lý tiếp. Với global install, CLI đổi command tương đối trong template thành dạng node "$HOME/.claude/hooks/scout-block.cjs"; với project install, path thường giữ ở dạng .claude/hooks/....
Đọc bảng hook theo 3 nhãn
Đừng gom mọi thứ thành "mặc định bật/tắt". Trạng thái của một hook có ba lớp khác nhau:
| Nhãn | Nghĩa khi audit |
|---|---|
script file | File .cjs có nằm trong .claude/hooks/. Có file chưa có nghĩa là hook đang chạy. |
wired | settings.json đã gắn script vào lifecycle event của Claude Code. Không wire thì Claude Code không tự gọi hook đó. |
runtime flag | Khi hook đã được gọi, code bên trong đọc .ck.json/DEFAULT_CONFIG/ENV để quyết định có chạy tiếp không. Một vài guard còn có công tắc con như privacyBlock hoặc simplify.gate.enabled. |
Bảng dưới đây là snapshot danh sách hook theo stable claudekit-engineer@2.19.1. Update 2026-06-09: claudekit-engineer@2.19.2-beta đang chuẩn bị remove task-completed-handler và teammate-idle-handler; khi upstream ClaudeKit release new version, danh sách này có thể còn 14 hook.
session-init · wired
SessionStart · runtime flag true
Project/env setup khi startup, resume, clear, compact.
usage-quota-cache-refresh · wired
SessionStart · UserPromptSubmit · PostToolUse · no flag
Không đọc hook flag riêng; chạy khi được wire.
simplify-gate · gate off
UserPromptSubmit · runtime flag true
Script được gọi, nhưng simplify.gate.enabled mặc định false.
dev-rules-reminder · wired
UserPromptSubmit · runtime flag true
Inject dev rules/context.
subagent-init · wired
SubagentStart · runtime flag true
Inject context cho subagent.
descriptive-name · wired
PreToolUse(Write) · runtime flag true
Nhắc đặt tên file/script rõ nghĩa.
scout-block · wired
PreToolUse(Bash/Glob/Grep/Read/Edit/Write) · runtime flag true
Chặn heavy dirs và glob quá rộng.
privacy-block · wired
PreToolUse(Bash/Glob/Grep/Read/Edit/Write) · runtime flag true · privacyBlock true
Chặn secret path, hỏi approval.
plan-format-kanban · wired
PostToolUse(Edit/Write/MultiEdit) · no flag
Không đọc hook flag riêng; warn format plan.
session-state · wired
PostToolUse · SubagentStop · Stop · runtime flag true
Ghi trạng thái session/task.
cook-after-plan-reminder · wired
SubagentStop(Plan) · key thiếu = enabled
Không có key riêng trong DEFAULT_CONFIG.hooks, nhưng isHookEnabled() chỉ tắt khi flag là false.
workflow-artifact-gate · not wired
runtime flag false
Opt-in cho artifact gate: cần wire hook và bật flag/gate config.
task-completed-handler · removing
TaskCompleted · chuẩn bị remove trong 2.19.2-beta
Agent Teams task completed; không nên coi là hook bền vững sau 2.19.1.
teammate-idle-handler · removing
TeammateIdle · chuẩn bị remove trong 2.19.2-beta
Agent Teams teammate idle; không nên coi là hook bền vững sau 2.19.1.
team-context-inject · not wired
key thiếu = enabled
Không có key riêng trong DEFAULT_CONFIG.hooks; chỉ có ý nghĩa khi workflow/team layer gọi tới.
usage-context-awareness · not wired
runtime flag true
Usage/context injection hook; không nằm trong settings.json template.
Điểm dễ sót: isHookEnabled() chỉ tắt khi hooks.<name> là false. Key thiếu thường được xem là enabled. Nhưng vài guard còn có công tắc riêng: privacy-block vẫn đọc key cũ privacyBlock=false, còn simplify-gate có simplify.gate.enabled và ENV CK_SIMPLIFY_DISABLED=1.
Manual bật/tắt và tự kiểm tra hook
Muốn chỉnh nhanh, sửa .ck.json ở scope cần tác động. Project config ưu tiên hơn global khi key được set rõ; key thiếu thì tiếp tục inherit/default. Với các hook đã được wire trong settings.json, đặt false là tắt, đặt true là bật lại sau khi scope cao hơn đã tắt. Tên hook trong cột Hook bên dưới cũng là key dùng trong hooks.<name>.
// .claude/.ck.json hoặc ~/.claude/.ck.json
{
"hooks": {
"scout-block": false,
"privacy-block": true
},
"privacyBlock": true,
"simplify": {
"gate": {
"enabled": true
}
}
}| Muốn làm | Chỉnh ở đâu | Lưu ý |
|---|---|---|
| Tắt một hook đã wire | .ck.json · {"hooks":{"scout-block":false}} | Hook script vẫn còn, nhưng runtime cho qua. |
| Bật lại hook bị tắt ở global | project .ck.json · {"hooks":{"scout-block":true}} | Key local rõ ràng override global. |
| Tắt privacy guard | .ck.json · {"hooks":{"privacy-block":false}} · .ck.json (key cũ) · {"privacyBlock":false} | privacyBlock=false là key cũ nhưng vẫn có hiệu lực. |
| Bật simplify-gate chặn thật | .ck.json · { "hooks": { "simplify-gate": true }, "simplify": { "gate": { "enabled": true } } } | Thiếu simplify.gate.enabled=true thì gate chưa bật chế độ chặn. |
| Tắt simplify-gate theo session/scope | settings.json · { "env": { "CK_SIMPLIFY_DISABLED": "1" } } | Env override mạnh hơn config gate. |
| Bật workflow-artifact-gate | settings.json · wire UserPromptSubmit / PreToolUse(Bash) · .ck.json · {"hooks":{"workflow-artifact-gate":true}} | Fresh install chưa wire sẵn, nên chỉ sửa \<code\>.ck.json\</code\> là chưa đủ. |
Muốn biết hook có được trigger không, nhìn lifecycle event chứ không nhìn tên file. Cùng một hook script chỉ chạy khi event/matcher trong settings.json khớp với hành động hiện tại. Bảng dưới đây là cách kiểm nhanh từng hook; hook not wired cần wire trước hoặc gọi bằng manual CLI nếu script hỗ trợ.
| Hook | Trigger thủ công | Ghi chú |
|---|---|---|
session-init | Mở, resume, clear hoặc compact session Claude Code. | SessionStart(startup|resume|clear|compact). |
usage-quota-cache-refresh | Mở session, gửi prompt mới, hoặc cập nhật Task/Todo. | Cache usage; không đọc hook flag riêng. |
simplify-gate | Gửi prompt có ý định ship/merge/pr/deploy/publish khi diff đủ lớn. | Cần simplify.gate.enabled=true; default không block. |
dev-rules-reminder | Gửi prompt mới. | UserPromptSubmit; inject rules theo TTL. |
subagent-init | Start subagent bằng Task/agent flow. | SubagentStart. |
descriptive-name | Để Claude định tạo file bằng Write. | PreToolUse(Write); nhắc tên file rõ. |
scout-block | Để Claude đọc node_modules, dist, hoặc glob quá rộng. | PreToolUse trên Bash/Glob/Grep/Read/Edit/Write. |
privacy-block | Để Claude đọc .env, key file, secret path. | PreToolUse; có thêm privacyBlock. |
plan-format-kanban | Để Claude Edit/Write/MultiEdit plan file. | PostToolUse; warn format, không đọc hook flag riêng. |
session-state | Cập nhật Task/Todo, kết thúc subagent, hoặc kết thúc turn. | PostToolUse, SubagentStop, Stop. |
cook-after-plan-reminder | Cho Plan subagent kết thúc. | SubagentStop(Plan); key thiếu vẫn enabled. |
workflow-artifact-gate | Wire vào UserPromptSubmit/PreToolUse(Bash), hoặc chạy script với --stage. | Fresh install chưa tự trigger hook mode. |
task-completed-handler | Hoàn tất task trong Agent Teams. | TaskCompleted; chuẩn bị remove trong claudekit-engineer@2.19.2-beta. |
teammate-idle-handler | Để teammate trong Agent Teams hết việc và đi idle. | TeammateIdle; chuẩn bị remove trong claudekit-engineer@2.19.2-beta. |
team-context-inject | Wire vào SubagentStart, rồi start team subagent. | Script có ý nghĩa khi agent id thuộc team. |
usage-context-awareness | Wire vào event mong muốn, hoặc dùng hook cache refresh đang wired sẵn. | Wrapper legacy quanh usage quota cache refresh. |
// ~/.claude/settings.json hoặc .claude/settings.json
{
"env": {
"CK_SIMPLIFY_DISABLED": "1"
}
}Nhóm guard · Chặn file/path
scout-block — chặn đọc thư mục rác
Agent hay đọc node_modules/, glob **/*.ts ở root (glob là mẫu khớp đường dẫn; **/*.ts nghĩa là mọi file .ts ở mọi thư mục con), cat dist/index.js. Mỗi lần là vài chục nghìn token nhét vào context, kéo cost và chất lượng turn sau xuống. scout-block.cjs đăng ký PreToolUse, chạy trước mọi Read/Bash/Glob/Grep.
# Baseline .ckignore — pattern-matcher.cjs xử lý
node_modules
dist
build
.next
.nuxt
__pycache__
.venv
venv
vendor
target
.git
coverageAllowlist quan trọng
Các lệnh build được cho qua. Những lệnh như npm build, go build, make, docker build vẫn chạy, kể cả khi quá trình build chạm node_modules hoặc dist. Nếu chặn cả nhóm này, các flow ship/test của CK dễ tự vấp ngay từ bước build.
Gap \#1 — khi hook crash
Fail-open: parse error đều dẫn tới exit 0, tool được cho qua. Hook có bug → guard lớp đó tắt âm thầm.
Nhóm guard · Chặn file/path nhạy cảm
privacy-block — chặn secret, bắt user duyệt rõ ràng
Agent đụng .env, id_rsa, *.pem, credentials.yaml — secret lộ vào transcript. Một khi vào context, có thể bị log, quote lại trong reviewer output, paste vào PR.
@@PRIVACY_PROMPT_START@@
{ "type": "PRIVACY_PROMPT", "question": {...}, "options": [...] }
@@PRIVACY_PROMPT_END@@Claude parse JSON, gọi AskUserQuestion. Nếu user duyệt, hook message hướng dẫn đọc file bằng đường approved, ví dụ cat ".env" sau khi đã hỏi; code cũng hỗ trợ prefix APPROVED:. Điểm chính: phải có approval rõ ràng, không để model tự diễn dịch consent.
Gap \#2 — ngoại lệ Bash
privacy-block cho Bash đi qua, chỉ cảnh báo. Bất kỳ ai có quyền chạy Bash đều đọc secret mà không qua approval flow.
Cảnh báo: nếu đã leak
Privacy-block chỉ chặn READ. Rotate credential ngay, audit conversation log, check git history xem secret có bị commit không.
Nhóm guard · Chặn sai bước
simplify-gate — chặn ship khi diff phình quá scope
Một task nhỏ có thể phình ra thành PR đụng quá nhiều file: sửa validation, thêm cleanup, đổi format, chỉnh vài helper lân cận. Khi agent nói "OK ship", simplify-gate.cjs đăng ký UserPromptSubmit, đọc git diff HEAD, chỉ xét khi prompt có: ship merge pr deploy publish.
400 - LOC tổng diff \> · 8 - file đụng \> · 200 - LOC thêm trong một file \>
Các ngưỡng mặc định của simplify.threshold: tổng dòng thêm+xóa, số file bị đụng, và dòng thêm lớn nhất trong một file. Gate chỉ chặn khi simplify.gate.enabled=true; các số này có thể override trong .ck.json.
Gap \#3 — default dễ hiểu nhầm
hooks.simplify-gate = true chỉ cho Claude Code gọi script. Muốn script thật sự chặn PR phình quá scope, phải bật thêm simplify.gate.enabled = true. Fresh install chưa bật flag này, nên gate chỉ chạy kiểm tra nhẹ và không block.
// project .ck.json — bật thật sự
{ "simplify": { "gate": { "enabled": true } } }matchedSeverity() bỏ qua "don't ship", "ship on" → "ship on Friday" cũng đi qua. Muốn tắt gate cho mọi session ở scope đó, đặt CK_SIMPLIFY_DISABLED=1 trong settings.json dưới key env.
Nhóm guard · Workflow / artifact gate
workflow-artifact-gate — 5 artifact JSON
Full pipeline → mỗi phase để lại file JSON ghi quyết định, như hoá đơn sau mỗi bước. Hook này được thiết kế để gắn vào UserPromptSubmit + PreToolUse(Bash), nhưng không nằm trong hook set chạy sẵn sau fresh install; muốn dùng phải opt-in.
| Artifact | Phase | Nội dung |
|---|---|---|
context-snippets.json | scout/plan | Snippet code đã đọc |
risk-gate.json | predict | High-risk flag, auto-stop |
verification.json | fix/cook | 5-point checklist |
review-decision.json | code-review | Reviewer verdict |
adversarial-validation.json | adversarial | Adversarial pass |
Gate này có hai mức xử lý. Ở bước rủi ro như ship, push, PR hoặc deploy, hook có thể dừng flow ngay và trả lý do về cho model (emitBlock()). Ở bước nhẹ hơn như finalize hoặc commit, hook cho flow đi tiếp nhưng thêm cảnh báo vào context để model tự sửa (emitSoft()).
Gap \#4 — workflow gate cần opt-in
workflow-artifact-gate là lớp kiểm artifact mạnh nhất, nhưng fresh install chưa tự gọi nó. Muốn dùng, phải wire hook trong settings.json và bật config trong .ck.json; nếu thiếu bước này, ship/push/PR/deploy không bị gate chặn.
Nhóm guard · Hard-gate skill
Hard-gate XML trong skill markdown
Hook chỉ chặn tool call. Có lỗi không phải tool call mà là trình tự: code trước plan, fix trước scout. CK gắn <HARD-GATE> vào skill markdown.
<HARD-GATE>
Do NOT write implementation code until a plan exists
and has been reviewed. Exception: --fast skips research
but still requires a plan step. User override: if user
explicitly says 'just code it', respect their instruction.
</HARD-GATE>ck:cook và ck:fix mỗi skill có 4 hard-gate (plan/scout-first, exact-req hoặc root-cause, no-side-effects).
Tại sao gọi là "hard"
Chữ "hard" dễ hiểu nhầm — không phải chặn bằng code. Là lời dặn trong prompt. Model bỏ qua → không có exit 2 chặn. Cách bọc XML tạo signal mạnh hơn rule thường để model khó hợp lý hoá việc đi tắt.
Nhóm guard · Thêm context
dev-rules-reminder — đưa rule vào context
dev-rules-reminder.cjs đăng ký UserPromptSubmit, đưa rules text vào mỗi prompt. Ở đây có hai lớp cần tách rõ: hook là cơ chế inject context, còn rule trong CLAUDE.md là nội dung được inject. TTL 5 phút theo (sessionId, baseDir) để tránh đốt token.
| File | Chống lại | Đặc trưng |
|---|---|---|
review-audit-self-decision | Audit reverse decision đã confirm | verified sticky |
development-rules | Skip test, fake data | YAGNI/KISS/DRY |
team-coordination-rules | Hai agent cùng edit | ownership glob |
commit-messages | Commit body dài | single-line |
orchestration-protocol | Pass full history | context isolation |
Đặc tính chung
Rules là text trong context, không phải code. Claude có thể lệch nếu prompt user đè. Bù lại rất dễ thêm/sửa. Phù hợp quy ước phong cách hơn guard bảo mật.
Nhóm guard · Guard skill user gọi
Guard skills — lớp guard user gọi
| Skill | Khi dùng | Bắt cái gì |
|---|---|---|
ck:security-scan | Pre-release | Secret, CVE, SQLi, XSS, path traversal |
ck:predict | Trước feature rủi ro | 5 persona, GO/CAUTION/STOP |
ck:scenario | Pre-impl | 12-dimension edge case sweep |
ck:ship | Pre-PR | Stop on test fail, never force-push |
code-reviewer agent chạy checklist 9 mục: concurrency, error boundary, API contract, backwards compat, input validation, auth/authz, N+1, data leak, fact-check. Guard cuối trước merge.
III\. Giới hạn & thực hành
Các gap đã biết
Đừng hiểu nhầm guard rail
- File-access guard nằm ở hook → fresh CK install dựa vào
scout-block/privacy-block, không phải một danh sáchpermissions.denyriêng cho secret/heavy dirs - Bash được miễn privacy-block → chỉ warn, không đi qua approval flow
- workflow-artifact-gate cần opt-in → gate mạnh nhất không chạy nếu chưa bật
- simplify-gate mặc định chưa chặn → cần bật rõ
- simplify-gate trượt bằng phrasing → "ship on Friday" được bỏ qua
- .ckignore có thể negate node_modules → kiểm tra trực tiếp
- Rules là lời dặn → Claude có thể lệch
- HARD-GATE XML cũng là lời dặn → có "User override"
Không có rate-limit / quota guard
Agent mất kiểm soát có thể call hàng nghìn Read/Glob/Bash. Hook CK không đếm số tool call, không tự dừng khi gần hết quota. Giới hạn quota/cost nằm ở Claude Code, provider hoặc account billing, không phải ở guard rail này.
Best practices & pitfalls
Best practices
- Đọc cả settings.json + .ck.json sau khi cài
- Bật workflow-artifact-gate cho repo ship production
- Muốn simplify-gate chặn thật: set
gate.enabled = true - Cần node_modules: project
.ckignoreoverride - Approval
.env: đọc kỹ, đừng auto-yes
Dễ nhầm
- Sửa global config nhưng tưởng đang sửa config của repo
- Tưởng simplify-gate đang chặn, trong khi mặc định chưa bật chế độ chặn
- Tưởng hook lỗi là tool sẽ bị chặn; thực tế hook fail thì thường cho qua
- Tưởng rule trong prompt cũng chặn được như code hook
- Secret đã vào commit rồi mới trông chờ privacy-block cứu lại
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? (outer + inner config)- Claude Code session hiện tại có đang bỏ qua permission prompt không?
- Có project
.ckignoreoverride?node_modulescó bị!allowlist? - Rule files trong CLAUDE.md có đầy đủ?
- Có hook nào crash âm thầm trong session này (check stderr)?
Glossary
Thuật ngữ nhanh
| Thuật ngữ | Nghĩa gọn |
|---|---|
| harness | Lớp điều phối giữa model và máy: gửi lệnh tool, quản quyền, chạy hook. Là chỗ gắn guard rail. |
| hook | Script nhỏ harness tự gọi tại thời điểm cố định trong vòng đời prompt/tool/session để xen vào kiểm tra hoặc ghi state. |
| lifecycle event | Các mốc hook được gọi: UserPromptSubmit (nhận prompt), PreToolUse (trước tool), PostToolUse (sau tool), Stop/SubagentStop (kết thúc session/subagent). |
| exit code | Số process trả khi kết thúc. 0 cho qua, 2 chặn, 1 báo lỗi nhưng không chặn. |
| fail-open | Khi hook lỗi/crash, harness cho tool chạy tiếp thay vì chặn. Guard tắt âm thầm. |
| transcript | Toàn bộ bản ghi hội thoại giữa user và agent trong session. |
| context | Vùng thông tin model "thấy" khi suy luận. Đầy file rác → cost cao, chất lượng giảm. |
| glob | Mẫu khớp đường dẫn. **/*.ts = mọi file .ts ở mọi thư mục con. |
| secret | Thông tin nhạy cảm: API key, private key, credential. Lộ vào transcript là rủi ro. |
| LOC | Lines of code — số dòng code, dùng đo độ lớn diff. |
| artifact | File JSON mỗi phase pipeline để lại, ghi quyết định để phase sau kiểm tra. |
Đọc đúng lớp, tin đúng mức
Khi agent có quyền rộng, đừng kết luận "CK đã cài là an toàn". Trước khi tin guard rail, kiểm tra hai nơi: settings.json đang wire hook nào, .ck.json đang bật/tắt gì.
Mỗi lớp bảo vệ một kiểu rủi ro: hook chặn tool call, rule nhắc hành vi, hard-gate giữ quy trình, guard skill chỉ chạy khi được gọi. Biết lớp nào đang chạy và lớp nào chỉ là lời dặn giúp audit đúng chỗ, trước khi lỗi lọt vào PR và đi tiếp lên PROD.
Chưa có ClaudeKit?
Nếu bạn đang build hệ thống guardrails, có thể tham khảo các pattern đã áp dụng trong ClaudeKit. Nếu cân nhắc mua ClaudeKit để dùng luôn bộ hooks, skills và workflow guard rails thay vì tự ghép từng mảnh, bạn có thể mua qua referral link này để được giảm 30%.
Inside ClaudeKit · Guard rails deep dives · claudekit-engineer@2.19.1
$ article.get locale=vi slug=guard-rails-in-claude-code-and-claudekit # REST hoặc MCP · đổi locale=en cho bản tiếng Anh
- Phiên bản
- v1.0.0
- Cập nhật
- 24/07/2026
- Giấy phép
- Bảo lưu mọi quyền
- Slug
- guard-rails-in-claude-code-and-claudekit