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

Guard rails:模型与操作之间的制动层

当 agent 拥有读取文件、运行 shell、修改代码和 ship PR 的权限时,prompt 里的一句提示远远不够。需要一层在 tool 真正运行之前进行检查的机制。

4guard 层
7guard rail 分组
2config 层
8已知缺口
13section
Case

一个小任务,权限却过宽

你交给 agent 一件小事:修复某个模块中的 validation。它为了更稳妥,多扫了几个目录,打开了敏感的 config 文件,然后顺手把一些不相关的 cleanup 也塞进同一个 PR。

表面上一切正常,测试也通过了。但 context 已混入无关文件,secret 可能已进入 transcript(你与 agent 之间对话的完整记录),而 review 也因为待修改部分和「顺手」部分混在同一个 PR 里而被稀释。

没有 guard rail

  • Glob 过宽——context 受污染
  • cat .env——secret 进入 transcript
  • Cleanup 超出 scope——review 被稀释
  • 测试通过就继续——缺少 scope 检查步骤

有 guard rail

  • Glob 过宽——scout-block exit 2
  • .env——privacy-block 询问用户
  • Scope 偏移——rule/hard-gate 提示回到主任务
  • Ship 前——simplify/review gate 重新检查 diff

Agent 不会自然而然地变得更谨慎。只是在它做某件事之前,有一层机制站出来问:这件事应该被允许运行吗?

核心要点

Hook 是真正的拦截层。

Guard rail 不会让模型变得更聪明。它在 tool 运行前检查行为。Rule、hard-gate 和 guard skill 是额外的引导层,有用但仍依赖模型或用户是否调用。

I. 概念

Section 01

agentic coding 中 guard rail 是什么

Guard rail 是介于 agent 与操作之间的一层:有风险的操作予以拦截,可疑的操作发出警告。它就像楼梯边缘的护栏:不会让你走得更好,但能降低踩空变成事故的概率。与 prompt 中的提示语(prompt instruction)不同,guard rail 运行在工具调度层,不依赖模型是否「记住」。

区分 guard rail 与提示语

Guard rail提示语
运行位置Harness,在模型之外在 context 内,由模型读取
强制执行代码硬性拦截模型自愿遵守
Context 过长仍然运行容易遗忘/跳过
模型理解偏差仍会拦截(若不 crash)随模型偏差
修改方式需改代码/config改文字即可
Section 02

Guard rail 如何工作

Harness 是包裹模型的运行时层。模型只决定「我想读这个文件」或「我想执行这条命令」;harness 才是接收 tool call、管理权限、调用 hook、决定让 tool 运行或拦截、并将结果返回给模型的一方。Hook 是 harness 在 tool call 生命周期的固定时间点自动调用的小脚本——收到 prompt 时、tool 执行前、tool 执行后——用于介入检查。由于所有真实操作都经过 harness,这里是挂载 guard rail 的地方。

概念背景延伸阅读:Duy /zuey/ 的 Harness Engineering là gì?

ClaudeKit Hooks 映射图

ClaudeKit Hooks 的更多细节可见 VividKit Guides

CLAUDE CODE LIFECYCLE User prompt task / intent Model 想要调用 tool UserPromptSubmit simplify-gate · dev-rules-reminder PreToolUse scout-block · privacy-block Tool 实际运行 Read · Bash · Edit · Write PostToolUse / Stop plan-format · session-state allow exit 0 · tool 运行 block exit 2 · 返回原因 inject additionalContext remember logs / state settings.json wire event .ck.json runtime flag ENV override payload: event · tool · input · cwd

Hook 不在模型内部。它位于 Claude Code 的生命周期中:settings.json 决定调用哪些 hook,.ck.json/ENV 决定运行时行为,hook 的输出可以允许运行、拦截、注入 context,或在 tool 或 session 结束后写入 state/artifact。

一次 tool call 经过 guard rail 的流程

HARNESS RUNTIME User prompt Prompt gate UserPromptSubmit · block? pass Model 决定调用 tool tool call: Read / Bash / Edit Pre-tool hook PreToolUse · scout / privacy exit 0 (allow) Tool exec 读取 / 写入 / 实际运行 result Post-tool hook PostToolUse · validate, scan Result 返回 Model block 拦截 提示用户修改 prompt exit 2 Tool 不运行 将原因返回给模型

关键点:pre-tool hook 返回 exit code。Exit 0 允许 tool 运行,exit 2 拦截并将原因推送给模型。流程中三个主要介入点有对应的技术名称:UserPromptSubmit(收到 prompt 时)、PreToolUse(tool 执行前)、PostToolUse(tool 执行后)。Stop/SubagentStop 在 session 或 subagent 结束时运行,因此位于上方的生命周期映射图中。

Exit code 的含义

Exit code 是进程结束时返回的数字。Claude Code 通过它决定 tool 是否运行:

  • exit 0——正常,tool 运行。stdout 作为 JSON output 读取。
  • exit 2——拦截。丢弃 stdout,将 stderr 推送给模型作为错误消息。
  • exit 1(或其他代码)——报错但不拦截。报告错误后 tool 仍继续运行。

只有 exit 2 才是真正的拦截。想要 enforce policy 的 hook 必须使用 exit 2——按 Unix 习惯误用 exit 1 会导致 guard 看似开启实则放行。

两种拦截方式

Hard · 代码

Hook exit 2,tool 不运行。但 hook crash 时 → Claude Code 放行(fail-open)。Hook 有 bug 会导致 guard 静默关闭。

Soft · 文本

向 context 添加文本(rule、hard-gate)。模型需自行遵守。强弱取决于模型。

收益
  • 保持 context 干净 · 防止 secret 进入 transcript
  • 维持节奏:plan → simplify → review
  • 在风险扩散前早期拦截——agent 准备读取 .env、扫描范围过宽,或将 scope 外的 cleanup 拉入 PR
  • 多层互补——hook 可能 fail-open,rule 可能被模型忽略,guard skill 可能未被调用;分散为多层可降低对单一拦截点的依赖

II. CK 中的实现

Section 03

CK 中的七类 guard rail

重要说明

全新 CK 安装后,文件访问 guard 位于 PreToolUse hook,如 scout-blockprivacy-block。若当前 Claude Code session 以跳过权限提示的模式运行,这些 hook 仍是 CK 的主要拦截层。但 CK 的 hook 是 fail-open 的:crash 或被禁用时,tool call 可能照常通过。

分组机制示例强制执行
文件/路径拦截PreToolUsescout-block代码 · fail-open
步骤错误拦截UserPromptSubmitsimplify-gatecode
注入 contextUserPromptSubmitdev-rules-remindercode
保持命名规范Pre/Post/Stopdescriptive-name代码 · 提示
Hard-gate skillXML markdown<HARD-GATE>提示语
Rule 提示语CLAUDE.mdreview-audit提示语
Guard skill用户调用ck:security-scanuser

各分组在哪里查阅

文件/路径拦截scout-blockprivacy-block · Section 05-06
步骤错误拦截simplify-gate、workflow gate · Section 07-08
注入 contextdev-rules-reminder 将文本注入 prompt · Section 10
保持命名规范descriptive-name · Section 04 的 hook 表格
Hard-gate skill<HARD-GATE> · Section 09
Rule 提示语CLAUDE.md rules 是被注入的内容 · Section 10
Guard skillck:security-scanck:ship · Section 11

9 个常见场景

场景处理层
读取 node_modules/react/scout-block,exit 2
读取 .env 检查 keyprivacy-block,exit 2 + approval prompt
在根目录使用 **/*.ts globscout-block broad-pattern
diff 已膨胀时触发 ship promptsimplify-gate,若 gate.enabled=true
没有 plan/review 就开始写代码ck:cook HARD-GATE
修改用户已确认的 thresholdreview-audit rule:修改前先询问
新建名称模糊的文件descriptive-name, PreToolUse(Write)
Plan 使用格式错误的链接/文本plan-format-kanban, PostToolUse(Edit/Write/MultiEdit)
两个 teammate 同时修改同一文件team-coordination rule,仅限 Agent Team
Section 04
Config 映射图 · 验证 hook 是否真正运行

Settings 与各 config 层

两层 config 决定哪些 guard 运行:settings.json 将 hook 挂载到 Claude Code 的生命周期;.ck.json 逐个启用/禁用 hook 并调整 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 在哪个时间点运行

以下片段仅展示全新 CK 安装中 PreToolUse 的一个切面:CK 提供 scout-blockprivacy-block,并将它们连接到生命周期,以便 Claude Code 在 tool 运行前调用。已安装机器上的完整 hook config 包含更多生命周期事件;需要查看的地方是 Claude Code 的 settings.json

{
  "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 是生命周期映射:用户发送 prompt 时调用哪个 hook,tool 运行前调用哪个 hook,tool 完成后由哪个 hook 继续处理。全局安装时,CLI 会将模板中的相对命令替换为 node "$HOME/.claude/hooks/scout-block.cjs" 形式;项目安装时,路径通常保持 .claude/hooks/... 形式。

按 3 个标签读取 hook 表格

不要把所有内容归为「默认开启/关闭」。一个 hook 的状态有三个不同层面:

标签审计时的含义
script file.cjs 文件是否位于 .claude/hooks/。有文件不代表 hook 正在运行。
wiredsettings.json 已将脚本挂载到 Claude Code 的生命周期事件。未 wire 则 Claude Code 不会自动调用该 hook。
runtime flag当 hook 被调用时,内部代码读取 .ck.json/DEFAULT_CONFIG/ENV 来决定是否继续执行。部分 guard 还有子开关,如 privacyBlocksimplify.gate.enabled

下表是 stable claudekit-engineer@2.19.1 的 hook 列表快照。2026-06-09 更新:claudekit-engineer@2.19.2-beta 准备移除 task-completed-handlerteammate-idle-handler;当 upstream ClaudeKit 发布新版本时,列表可能变为 14 个 hook。

session-initwired
SessionStart · runtime flag true

启动、恢复、clear、compact 时的项目/环境初始化。

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

不读取独立 hook flag;wire 后即运行。

simplify-gategate off
UserPromptSubmit · runtime flag true

脚本被调用,但 simplify.gate.enabled 默认为 false。

dev-rules-reminderwired
UserPromptSubmit · runtime flag true

注入 dev rules/context。

subagent-initwired
SubagentStart · runtime flag true

为 subagent 注入 context。

descriptive-namewired
PreToolUse(Write) · runtime flag true

提示为文件/脚本取有意义的名称。

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

拦截重型目录和过宽的 glob。

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

拦截 secret 路径,请求 approval。

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

不读取独立 hook flag;警告 plan 格式。

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

写入 session/task 状态。

cook-after-plan-reminderwired
SubagentStop(Plan) · key 缺失 = enabled

DEFAULT_CONFIG.hooks 中无独立 key,但 isHookEnabled() 仅在 flag 为 false 时禁用。

workflow-artifact-gatenot wired
runtime flag false

artifact gate 需 opt-in:须 wire hook 并启用 flag/gate config。

task-completed-handlerremoving
TaskCompleted · 准备在 2.19.2-beta 中移除

Agent Teams task completed;2.19.1 之后不应视为稳定 hook。

teammate-idle-handlerremoving
TeammateIdle · 准备在 2.19.2-beta 中移除

Agent Teams teammate idle;2.19.1 之后不应视为稳定 hook。

team-context-injectnot wired
key 缺失 = enabled

DEFAULT_CONFIG.hooks 中无独立 key;仅在 workflow/team 层调用时有意义。

usage-context-awarenessnot wired
runtime flag true

Usage/context injection hook;不在 settings.json 模板中。

容易忽略的点:isHookEnabled() 只在 hooks.<name>false 时禁用。缺少 key 通常被视为 enabled。但部分 guard 还有独立开关:privacy-block 仍读取旧 key privacyBlock=falsesimplify-gatesimplify.gate.enabled 和 ENV CK_SIMPLIFY_DISABLED=1

手动启用/禁用与 hook 自检

如需快速调整,在目标 scope 修改 .ck.json。当 key 明确设置时,项目 config 优先于全局;缺少 key 时继续 inherit/默认。对于已在 settings.json 中 wire 的 hook,设为 false 即禁用,设为 true 可在上层 scope 禁用后重新启用。Hook 列中的 hook 名称也是 hooks.<name> 中使用的 key。

// .claude/.ck.json 或 ~/.claude/.ck.json
{
  "hooks": {
    "scout-block": false,
    "privacy-block": true
  },
  "privacyBlock": true,
  "simplify": {
    "gate": {
      "enabled": true
    }
  }
}
操作目标修改位置说明
禁用一个已 wire 的 hook
.ck.json{"hooks":{"scout-block":false}}
Hook 脚本仍存在,但运行时放行。
重新启用已在 global 禁用的 hook
project .ck.json{"hooks":{"scout-block":true}}
本地明确的 key 覆盖全局。
禁用 privacy guard
.ck.json{"hooks":{"privacy-block":false}}
.ck.json(旧 key){"privacyBlock":false}
privacyBlock=false 是旧 key,但仍有效。
真正启用 simplify-gate 拦截
.ck.json{ "hooks": { "simplify-gate": true }, "simplify": { "gate": { "enabled": true } } }
缺少 simplify.gate.enabled=true 则 gate 未开启拦截模式。
按 session/scope 禁用 simplify-gate
settings.json{ "env": { "CK_SIMPLIFY_DISABLED": "1" } }
ENV 覆盖优先于 config gate。
启用 workflow-artifact-gate
settings.jsonwire UserPromptSubmit / PreToolUse(Bash)
.ck.json{"hooks":{"workflow-artifact-gate":true}}
全新安装未预置 wire,仅修改 <code>.ck.json</code> 不够。

想知道 hook 是否被触发,看生命周期事件而非文件名。同一 hook 脚本只有当 settings.json 中的 event/matcher 与当前操作匹配时才运行。下表是快速检查每个 hook 的方法;not wired 的 hook 需先 wire 或通过手动 CLI 调用(若脚本支持)。

Hook手动触发方式备注
session-init打开、恢复、clear 或 compact Claude Code session。SessionStart(startup|resume|clear|compact)
usage-quota-cache-refresh打开 session、发送新 prompt,或更新 Task/Todo。缓存用量;不读取独立 hook flag。
simplify-gate发送含 ship/merge/pr/deploy/publish 意图的 prompt,且 diff 足够大时。需要 simplify.gate.enabled=true;默认不拦截。
dev-rules-reminder发送新 prompt。UserPromptSubmit;按 TTL 注入 rules。
subagent-init通过 Task/agent flow 启动 subagent。SubagentStart.
descriptive-name让 Claude 通过 Write 创建文件。PreToolUse(Write);提示文件名清晰。
scout-block让 Claude 读取 node_modulesdist,或使用过宽的 glob。PreToolUse 作用于 Bash/Glob/Grep/Read/Edit/Write。
privacy-block让 Claude 读取 .env、key 文件、secret 路径。PreToolUse;附带 privacyBlock
plan-format-kanban让 Claude 对 plan 文件执行 Edit/Write/MultiEdit。PostToolUse;警告格式,不读取独立 hook flag。
session-state更新 Task/Todo、结束 subagent,或结束当前 turn。PostToolUseSubagentStopStop
cook-after-plan-reminder让 Plan subagent 结束。SubagentStop(Plan);缺少 key 时仍为 enabled。
workflow-artifact-gateWire 到 UserPromptSubmit/PreToolUse(Bash),或以 --stage 运行脚本。全新安装不会自动触发 hook 模式。
task-completed-handler在 Agent Teams 中完成任务。TaskCompleted;准备在 claudekit-engineer@2.19.2-beta 中移除。
teammate-idle-handler让 Agent Teams 中的 teammate 完成工作并进入 idle 状态。TeammateIdle;准备在 claudekit-engineer@2.19.2-beta 中移除。
team-context-injectWire 到 SubagentStart,然后启动 team subagent。当 agent id 属于 team 时脚本才有意义。
usage-context-awarenessWire 到目标事件,或使用已 wire 的 hook cache 刷新。usage quota cache 刷新的遗留 wrapper。
// ~/.claude/settings.json 或 .claude/settings.json
{
  "env": {
    "CK_SIMPLIFY_DISABLED": "1"
  }
}
Section 05
Guard 分组 · 文件/路径拦截

scout-block——拦截读取无用目录

Agent 经常读取 node_modules/、在根目录使用 **/*.ts glob(glob 是路径匹配模式;**/*.ts 表示所有子目录中的所有 .ts 文件)、cat dist/index.js。每次都会将数万 token 塞入 context,拉高成本并降低后续 turn 的质量。scout-block.cjs 注册 PreToolUse,在所有 Read/Bash/Glob/Grep 之前运行。

# Baseline .ckignore——由 pattern-matcher.cjs 处理
node_modules
dist
build
.next
.nuxt
__pycache__
.venv
venv
vendor
target
.git
coverage
重要 Allowlist

构建命令被放行。npm buildgo buildmakedocker build 等命令仍可运行,即使构建过程涉及 node_modulesdist。若拦截这类命令,CK 的 ship/test 流程很容易在构建阶段就自行卡住。

Gap #1——hook crash 时

Fail-open:任何解析错误都会导致 exit 0,tool 被放行。Hook 有 bug → 该层 guard 静默关闭。

Section 06
Guard 分组 · 拦截敏感文件/路径

privacy-block——拦截 secret,强制用户明确审批

Agent 接触 .envid_rsa*.pemcredentials.yaml——secret 会泄露进 transcript。一旦进入 context,可能被记录、在 reviewer output 中被引用,或粘贴到 PR 中。

@@PRIVACY_PROMPT_START@@
{ "type": "PRIVACY_PROMPT", "question": {...}, "options": [...] }
@@PRIVACY_PROMPT_END@@

Claude 解析 JSON,调用 AskUserQuestion。若用户批准,hook 消息会引导通过已批准路径读取文件,例如在询问后执行 cat ".env";代码也支持 APPROVED: 前缀。核心点:必须有明确的 approval,不能让模型自行解读 consent。

Gap #2——Bash 例外

privacy-block 对 Bash 放行,仅发出警告。任何有 Bash 运行权限的人都可以不经 approval flow 直接读取 secret。

警告:若已泄露

Privacy-block 只拦截 READ。立即轮换凭证,审计对话日志,检查 git history 确认 secret 是否已被 commit。

Section 07
Guard 分组 · 拦截步骤错误

simplify-gate——当 diff 膨胀超出 scope 时拦截 ship

一个小任务可能膨胀成触及过多文件的 PR:修复 validation、添加 cleanup、改格式、调整几个相邻 helper。当 agent 说「OK ship」时,simplify-gate.cjs 注册 UserPromptSubmit,读取 git diff HEAD,仅在 prompt 包含以下内容时判断:ship merge pr deploy publish

400diff 总 LOC >
8涉及文件数 >
200单文件新增 LOC >

simplify.threshold 的默认值:总新增+删除行数、触及文件数、单个文件中的最大新增行数。只有在 simplify.gate.enabled=true 时 gate 才会拦截;这些值可在 .ck.json 中覆盖。

Gap #3——默认值容易误解

hooks.simplify-gate = true 只是让 Claude Code 调用脚本。若要脚本真正拦截膨胀的 PR,还需启用 simplify.gate.enabled = true。全新安装未启用此 flag,因此 gate 只进行轻度检查,不会 block。

// project .ck.json——真正启用
{ "simplify": { "gate": { "enabled": true } } }

matchedSeverity() 会忽略 "don't ship""ship on"——"ship on Friday" 也会通过。若要在该 scope 的所有 session 中关闭 gate,在 settings.jsonenv key 下设置 CK_SIMPLIFY_DISABLED=1

Section 08
Guard 分组 · Workflow / artifact gate

workflow-artifact-gate——5 个 artifact JSON

完整 pipeline → 每个 phase 留下一个记录决策的 JSON 文件,如同每步之后的收据。此 hook 设计用于挂载到 UserPromptSubmit + PreToolUse(Bash),但不在全新安装后默认运行的 hook 集中;需要使用须 opt-in。

ArtifactPhase内容
context-snippets.jsonscout/plan已读取的代码片段
risk-gate.jsonpredict高风险 flag,auto-stop
verification.jsonfix/cook5 项检查清单
review-decision.jsoncode-reviewReviewer 结论
adversarial-validation.jsonadversarial对抗性检查

此 gate 有两种处理级别。在 ship、push、PR 或 deploy 等高风险步骤,hook 可立即停止流程并将原因返回给模型(emitBlock())。在 finalize 或 commit 等较轻步骤,hook 让流程继续但向 context 添加警告供模型自行修正(emitSoft())。

Gap #4——workflow gate 需 opt-in

workflow-artifact-gate 是最强的 artifact 检查层,但全新安装不会自动调用它。使用前须在 settings.json 中 wire hook 并在 .ck.json 中启用 config;否则 ship/push/PR/deploy 不会被 gate 拦截。

Section 09
Guard 分组 · Hard-gate skill

Skill markdown 中的 Hard-gate XML

Hook 只拦截 tool call。有一类错误不是 tool call,而是流程顺序:在 plan 前写代码,在 scout 前 fix。CK 在 skill markdown 中嵌入 <HARD-GATE>

<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 各有 4 个 hard-gate(plan/scout-first、exact-req 或 root-cause、no-side-effects)。

为什么叫「hard」

「hard」这个词容易误解——并非代码硬性拦截。它是 prompt 中的提示语。模型忽略时没有 exit 2 拦截。XML 包裹方式比普通 rule 产生更强的信号,使模型更难合理化跳过步骤的行为。

Section 10
Guard 分组 · 注入 context

dev-rules-reminder——将 rule 注入 context

dev-rules-reminder.cjs 注册 UserPromptSubmit,将 rules 文本注入每个 prompt。这里需要区分两层:hook 是注入 context 的机制,而 CLAUDE.md 中的 rule 是被注入的内容。按 (sessionId, baseDir) 设置 5 分钟 TTL 以避免 token 消耗。

文件防范特征
review-audit-self-decisionaudit 反转已确认的决策verified sticky
development-rules跳过测试、使用假数据YAGNI/KISS/DRY
team-coordination-rules两个 agent 同时编辑ownership glob
commit-messages冗长的 commit bodysingle-line
orchestration-protocol传递完整历史记录context isolation
共同特性

Rules 是 context 中的文本,不是代码。若用户 prompt 覆盖,Claude 可能偏离。但易于添加/修改。更适合风格约定,而非安全性 guard。

Section 11
Guard 分组 · 用户调用的 guard skill

Guard skills——用户调用的 guard 层

Skill使用时机检查内容
ck:security-scanPre-releaseSecret、CVE、SQLi、XSS、path traversal
ck:predict高风险 feature 前5 个 persona,GO/CAUTION/STOP
ck:scenarioPre-impl12 维度边界案例扫描
ck:shipPre-PR测试失败即停止,永不 force-push

code-reviewer agent 运行 9 项检查清单:并发、error boundary、API contract、向后兼容、输入验证、auth/authz、N+1、数据泄露、事实核查。合并前的最后一道 guard。

III. 局限与实践

Section 12

已知缺口

不要误解 guard rail
  1. 文件访问 guard 位于 hook——全新 CK 安装依赖 scout-block/privacy-block,而非针对 secret/重型目录的独立 permissions.deny 列表
  2. Bash 免于 privacy-block——仅警告,不经过 approval flow
  3. workflow-artifact-gate 需 opt-in——最强 gate 若未启用则不运行
  4. simplify-gate 默认未启用拦截——需明确启用
  5. simplify-gate 可被措辞绕过——「ship on Friday」被忽略
  6. .ckignore 可能 negate node_modules——直接检查确认
  7. Rules 是提示语——Claude 可能偏离
  8. HARD-GATE XML 也是提示语——存在「User override」
没有 rate-limit / quota guard

失控的 agent 可能调用数千次 Read/Glob/Bash。CK hook 不计数 tool call,不会在接近 quota 时自动停止。Quota/cost 限制由 Claude Code、provider 或账户计费决定,不在这层 guard rail 的职责范围内。

Section 13

Best practices 与常见陷阱

Best practices

  • 安装后同时阅读 settings.json + .ck.json
  • 生产环境仓库启用 workflow-artifact-gate
  • 要让 simplify-gate 真正拦截:设置 gate.enabled = true
  • 需要 node_modules:用项目 .ckignore override
  • 审批 .env:仔细阅读,不要自动确认

容易踩的坑

  • 修改了 global config,却以为在修改仓库的 config
  • 以为 simplify-gate 正在拦截,实际上默认未启用拦截模式
  • 以为 hook 报错会导致 tool 被拦截;实际上 hook 失败通常放行
  • 以为 prompt 中的 rule 也能像 code hook 一样拦截
  • Secret 已进入 commit 才寄望于 privacy-block 补救

相信 guard rail 前的 6 个检查问题

Glossary

术语速查

术语简明释义
harness模型与机器之间的调度层:发送 tool 命令、管理权限、运行 hook。是挂载 guard rail 的地方。
hookHarness 在 prompt/tool/session 生命周期固定时间点自动调用的小脚本,用于介入检查或写入 state。
lifecycle eventHook 被调用的时间点:UserPromptSubmit(收到 prompt)、PreToolUse(tool 执行前)、PostToolUse(tool 执行后)、Stop/SubagentStop(session/subagent 结束)。
exit code进程结束时返回的数字。0 放行,2 拦截,1 报错但不拦截。
fail-open当 hook 报错/crash 时,harness 让 tool 继续运行而非拦截。Guard 静默关闭。
transcriptsession 中用户与 agent 之间对话的完整记录。
context模型推理时「看到」的信息区域。充斥无用文件 → 成本高、质量下降。
glob路径匹配模式。**/*.ts = 所有子目录中的所有 .ts 文件。
secret敏感信息:API key、private key、credential。泄露进 transcript 即为风险。
LOCLines of code——代码行数,用于衡量 diff 大小。
artifact每个 pipeline phase 留下的 JSON 文件,记录决策供后续 phase 检查。

读对层级,信对程度

当 agent 拥有广泛权限时,不要下结论「安装了 CK 就安全了」。在相信 guard rail 之前,检查两处:settings.json 当前 wire 了哪些 hook,.ck.json 当前启用/禁用了什么。

每层防护针对一类风险:hook 拦截 tool call,rule 提示行为,hard-gate 维护流程,guard skill 仅在被调用时运行。了解哪层正在运行、哪层只是提示语,有助于在错误进入 PR 并流向 PROD 之前在正确的地方进行审计。

还没有 ClaudeKit?

如果你正在构建 guardrails 系统,可以参考 ClaudeKit 中已经应用的 patterns。 如果你正在考虑购买 ClaudeKit,想直接使用 hooks、skills 和 workflow guard rails,而不是手动拼装每一层,可以通过这个 referral link 购买并享 20% 折扣。

获取 20% 折扣
Inside ClaudeKit · Guard rails deep dives · claudekit-engineer@2.19.1