VI EN ZH JA
Inside ClaudeKit · No. 03claudekit-engineer@2.19.1
Inside ClaudeKit · Guard rails deep dives

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

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.

4lớp guard
7nhóm guard rail
2lớp config
8gap đã biết
13section
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

Section 01

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 railLời dặn
Chạy ở đâuHarness, ngoài modelTrong context, model đọc
Ép buộcCode chặn thậtModel tự nguyện tuân
Context dàiVẫn chạyDễ quên / trượt
Model hiểu lệchVẫn chặn (nếu không crash)Lệch theo model
Sửa đổiĐụng code/configSửa text là xong
Section 02

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.

CLAUDE CODE LIFECYCLE User prompt task / intent Model muốn gọi tool UserPromptSubmit simplify-gate · dev-rules-reminder PreToolUse scout-block · privacy-block Tool chạy thật Read · Bash · Edit · Write PostToolUse / Stop plan-format · session-state allow exit 0 · tool chạy block exit 2 · trả lý do inject additionalContext remember logs / state settings.json wire event .ck.json runtime flag ENV override payload: event · tool · input · cwd

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

HARNESS RUNTIME User prompt Prompt gate UserPromptSubmit · block? pass Model quyết định gọi tool tool call: Read / Bash / Edit Pre-tool hook PreToolUse · scout / privacy exit 0 (allow) Tool exec đọc / ghi / chạy thật result Post-tool hook PostToolUse · validate, scan Result về Model block Chặn nhắc user sửa prompt exit 2 Tool KHÔNG chạy trả lý do về model

Đ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 2chặ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

Section 03

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-blockprivacy-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ómCơ chếVí dụÉp buộc
Chặn file/pathPreToolUsescout-blockcode · fail-open
Chặn sai bướcUserPromptSubmitsimplify-gatecode
Thêm contextUserPromptSubmitdev-rules-remindercode
Giữ tên sạchPre/Post/Stopdescriptive-namecode · nhắc
Hard-gate skillXML markdown<HARD-GATE>lời dặn
Rule lời dặnCLAUDE.mdreview-auditlời dặn
Guard skillUser gọick:security-scanuser

Nhóm nào đọc ở đâu

Chặn file/pathscout-block, privacy-block · Section 05-06
Chặn sai bướcsimplify-gate, workflow gate · Section 07-08
Thêm contextdev-rules-reminder inject text vào prompt · Section 10
Giữ tên sạchdescriptive-name · hook grid trong Section 04
Hard-gate skill<HARD-GATE> · Section 09
Rule lời dặnCLAUDE.md rules là nội dung được inject · Section 10
Guard skillck:security-scan, ck:ship · Section 11

9 tình huống quen thuộc

Tình huốngLớp xử lý
Đọc node_modules/react/scout-block, exit 2
Đọc .env check keyprivacy-block, exit 2 + approval prompt
Glob **/*.ts ở rootscout-block broad-pattern
Prompt ship khi diff đã phình tosimplify-gate, nếu gate.enabled=true
Bắt đầu code khi chưa có plan/reviewck:cook HARD-GATE
Đổi threshold user đã chốtreview-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 formatplan-format-kanban, PostToolUse(Edit/Write/MultiEdit)
Hai teammate đụng cùng fileteam-coordination rule, chỉ trong Agent Team
Section 04
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/*.cjs

settings.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-blockprivacy-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ãnNghĩa khi audit
script fileFile .cjs có nằm trong .claude/hooks/. Có file chưa có nghĩa là hook đang chạy.
wiredsettings.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 flagKhi 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-handlerteammate-idle-handler; khi upstream ClaudeKit release new version, danh sách này có thể còn 14 hook.

session-initwired
SessionStart · runtime flag true

Project/env setup khi startup, resume, clear, compact.

usage-quota-cache-refreshwired
SessionStart · UserPromptSubmit · PostToolUse · no flag

Không đọc hook flag riêng; chạy khi được wire.

simplify-gategate off
UserPromptSubmit · runtime flag true

Script được gọi, nhưng simplify.gate.enabled mặc định false.

dev-rules-reminderwired
UserPromptSubmit · runtime flag true

Inject dev rules/context.

subagent-initwired
SubagentStart · runtime flag true

Inject context cho subagent.

descriptive-namewired
PreToolUse(Write) · runtime flag true

Nhắc đặt tên file/script rõ nghĩa.

scout-blockwired
PreToolUse(Bash/Glob/Grep/Read/Edit/Write) · runtime flag true

Chặn heavy dirs và glob quá rộng.

privacy-blockwired
PreToolUse(Bash/Glob/Grep/Read/Edit/Write) · runtime flag true · privacyBlock true

Chặn secret path, hỏi approval.

plan-format-kanbanwired
PostToolUse(Edit/Write/MultiEdit) · no flag

Không đọc hook flag riêng; warn format plan.

session-statewired
PostToolUse · SubagentStop · Stop · runtime flag true

Ghi trạng thái session/task.

cook-after-plan-reminderwired
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-gatenot wired
runtime flag false

Opt-in cho artifact gate: cần wire hook và bật flag/gate config.

task-completed-handlerremoving
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-handlerremoving
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-injectnot 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-awarenessnot 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>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-gatesimplify.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àmChỉnh ở đâuLư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.jsonwire 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ợ.

HookTrigger thủ côngGhi chú
session-initMở, resume, clear hoặc compact session Claude Code.SessionStart(startup|resume|clear|compact).
usage-quota-cache-refreshMở session, gửi prompt mới, hoặc cập nhật Task/Todo.Cache usage; không đọc hook flag riêng.
simplify-gateGử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-reminderGửi prompt mới.UserPromptSubmit; inject rules theo TTL.
subagent-initStart 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-stateCập nhật Task/Todo, kết thúc subagent, hoặc kết thúc turn.PostToolUse, SubagentStop, Stop.
cook-after-plan-reminderCho Plan subagent kết thúc.SubagentStop(Plan); key thiếu vẫn enabled.
workflow-artifact-gateWire vào UserPromptSubmit/PreToolUse(Bash), hoặc chạy script với --stage.Fresh install chưa tự trigger hook mode.
task-completed-handlerHoà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-injectWire vào SubagentStart, rồi start team subagent.Script có ý nghĩa khi agent id thuộc team.
usage-context-awarenessWire 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"
  }
}
Section 05
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
coverage
Allowlist 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.

Section 06
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.yamlsecret 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.

Section 07
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.

400LOC tổng diff >
8file đụng >
200LOC 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.

Section 08
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.

ArtifactPhaseNội dung
context-snippets.jsonscout/planSnippet code đã đọc
risk-gate.jsonpredictHigh-risk flag, auto-stop
verification.jsonfix/cook5-point checklist
review-decision.jsoncode-reviewReviewer verdict
adversarial-validation.jsonadversarialAdversarial 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.

Section 09
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:cookck: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.

Section 10
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.

FileChống lạiĐặc trưng
review-audit-self-decisionAudit reverse decision đã confirmverified sticky
development-rulesSkip test, fake dataYAGNI/KISS/DRY
team-coordination-rulesHai agent cùng editownership glob
commit-messagesCommit body dàisingle-line
orchestration-protocolPass full historycontext 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.

Section 11
Nhóm guard · Guard skill user gọi

Guard skills — lớp guard user gọi

SkillKhi dùngBắt cái gì
ck:security-scanPre-releaseSecret, CVE, SQLi, XSS, path traversal
ck:predictTrước feature rủi ro5 persona, GO/CAUTION/STOP
ck:scenarioPre-impl12-dimension edge case sweep
ck:shipPre-PRStop 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

Section 12

Các gap đã biết

Đừng hiểu nhầm guard rail
  1. 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ách permissions.deny riêng cho secret/heavy dirs
  2. Bash được miễn privacy-block → chỉ warn, không đi qua approval flow
  3. workflow-artifact-gate cần opt-in → gate mạnh nhất không chạy nếu chưa bật
  4. simplify-gate mặc định chưa chặn → cần bật rõ
  5. simplify-gate trượt bằng phrasing → "ship on Friday" được bỏ qua
  6. .ckignore có thể negate node_modules → kiểm tra trực tiếp
  7. Rules là lời dặn → Claude có thể lệch
  8. 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.

Section 13

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 .ckignore override
  • 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

Glossary

Thuật ngữ nhanh

Thuật ngữNghĩa gọn
harnessLớ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.
hookScript 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 eventCá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 codeSố 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-openKhi hook lỗi/crash, harness cho tool chạy tiếp thay vì chặn. Guard tắt âm thầm.
transcriptToàn bộ bản ghi hội thoại giữa user và agent trong session.
contextVùng thông tin model "thấy" khi suy luận. Đầy file rác → cost cao, chất lượng giảm.
globMẫu khớp đường dẫn. **/*.ts = mọi file .ts ở mọi thư mục con.
secretThông tin nhạy cảm: API key, private key, credential. Lộ vào transcript là rủi ro.
LOCLines of code — số dòng code, dùng đo độ lớn diff.
artifactFile 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 20%.

Nhận giảm 20%
Inside ClaudeKit · Guard rails deep dives · claudekit-engineer@2.19.1