关于 ship-gate
ship-gate 是提交前检查暂存差异的安全门技能,专门查找凭据、调试残留、注释掉的代码块及意外的大型或二进制文件。它只检查已暂存内容,并以 BLOCK 或 PASS 给出结论。
主要功能
- 01仅扫描已暂存差异
- 02检查密钥和 API 凭据
- 03查找调试代码与注释代码块
- 04识别大型或二进制新增文件
- 05按问题位置报告并给出结论
适用场景
- 01提交代码前检查暂存内容
- 02排查误提交的密钥或环境文件
- 03发现遗留调试语句和大型文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ unlearndev/ skills --skill ship-gate安装后在 Claude Code 中输入/ship-gate确认已加载。
详细介绍
提交前检查暂存的差异
扫描当前所有已暂存要提交的内容,并标记任何不应提交的内容。这是一项聚焦于安全性的检查,不是代码审查——不要评论风格、命名、架构或正确性。只查找以下四类问题,报告每项问题所在的文件和行号,并说明其重要性。最后给出一个结论。
1. 获取暂存的差异
只检查实际已暂存的内容(--cached)。未暂存的更改不在检查范围内。
git diff --cached --stat # overview of staged files
git diff --cached # full staged diff (read this)
git diff --cached --numstat # added/removed line counts; "-" marks binary files
git diff --cached --name-only --diff-filter=A # newly ADDED files (for size/binary checks)
阅读完整的暂存差异。检查调试代码、密钥和已注释掉的代码块时,只考虑新增行(以 + 开头的行)——作为上下文显示的既有行并非本次提交引入,不应标记。检查新增文件或二进制文件时,检查报告为新增的工作树文件。
如果没有暂存内容,请明确说明并停止——没有内容需要检查。
2. 需要标记的内容
根据以下各项逐一检查暂存差异。大多数提交只会触发少数几项,这是正常的。不要为了凑足类别而捏造问题;每项问题都必须指向真实新增的行或文件。
密钥和 API 密钥
标记看起来是真实凭据而非引用的新增行。留意:
- 将字面量秘密值赋给变量的情况:API 密钥、令牌、密码、私钥、含有凭据的连接字符串。
- 可识别的密钥格式:
AKIA…(AWS 访问密钥)、sk-…/sk-ant-…(OpenAI/Anthropic)、ghp_…/gho_…(GitHub 令牌)、xox[baprs]-…(Slack)、GoogleAIza…、Stripesk_live_…/rk_live_…、JWT(eyJ…)、-----BEGIN … PRIVATE KEY-----块。 - 赋给
*_KEY、*_SECRET、*_TOKEN、*_PASSWORD、PASSWD、*_DSN、AUTH、CREDENTIAL等名称的高熵长字符串。
区分真实密钥与安全内容,避免误报:
- **安全/不要标记:**占位符(
your-api-key-here、xxxxx、changeme、example、<token>)、值为空或为虚构值的.env.example条目、从配置中读取的值(env('STRIPE_SECRET')、process.env.X、config(...))、明显的测试样例。 - **标记:**提交到源码中的具体可疑密钥值,以及暂存以待提交的真实
.env文件中出现的任何密钥(含有有效值的.env几乎绝不应提交——请明确指出这一点)。
如果无法确定字符串是否为有效密钥,请标记为疑似,并说明原因——与其不作声,不如将其提交给人工确认。
遗留调试代码
根据文件所用语言,标记明显遗留的调试脚手架新增行:
- PHP:
dd(、dump(、ddd(、var_dump(、未被返回或使用的print_r(、ray(、error_log(、临时新增的\Log::debug(、Debugbar::。 - **JS / TS / Vue:**为调试而新增的
console.log(/console.debug(/console.warn(、debugger;、alert(。 - 通用:
TODO: remove、FIXME、XXX、临时的sleep(、硬编码的测试开关,例如if (true)/return; // skip。
请酌情判断:合法错误处理程序中的 console.error,或应用实际日志记录所需的日志调用,不属于调试残留。只标记看起来是遗忘的调试语句。
大段已注释掉的代码
标记新增的连续已注释代码(不是说明性文字)。连续约 5 行或更多已注释掉的代码块属于应删除而非提交的死代码。短注释、文档注释或单行说明都可以;不要标记这些内容。根据文件的注释语法(//、#、/* … */、``),识别那些看起来是代码(语句、函数体、标记语言)的内容。
意外添加的大型或二进制文件
检查新添加的文件(--diff-filter=A):
- 二进制文件 —
git diff --cached --numstat对二进制文件的添加和删除列都会显示-。标记看起来并非有意添加的二进制文件:编译输出、归档文件、被转储到源代码中的图像、.zip、.tar、.gz、.pdf、.sqlite、.db、字体、媒体文件。请自行判断:放在资源目录中的有意添加的资源没有问题。 - 大型文件 — 检查新增文件在磁盘上的大小(例如使用
wc -c,或使用git cat-file -s :<path>检查暂存区中的 blob)。标记所有大约超过 1 MB的文件;无论大小,如果文件类型本不应出现在 git 中,也要标记(vendor/、node_modules/、*.log、构建产物、含真实值的.env、.DS_Store等操作系统垃圾文件)。
3. 报告发现
输出 Markdown。按上述四个类别分组列出发现;只包含确实有发现的类别。每项发现需提供:
- 文件和行号 —
path/to/file.php:42。使用新文件中新增行的行号。对于已注释的代码块,给出起止行号范围。对于整个文件的问题(二进制文件/大型文件/.env),只需提供路径。 - 内容 — 有问题的代码片段(截断/隐去机密信息,只展示足以定位的内容,例如
STRIPE_SECRET=sk_live_51H…;绝不要输出完整的有效密钥)。 - 原因 — 简短说明为何不应提交。
每项发现控制在一两行内。不要写引言,也不要评论代码质量。
4. 判定结果
以一个加粗的判定词结尾:**BLOCK** 或 **PASS**,后面不得有任何内容。不要添加总结或解释;上面的发现已说明原因。
- BLOCK — 只要存在任何机密/API 密钥,或任何其他严重到不应提交的问题(真实的
.env、已提交的凭据、意外的二进制/大型文件、明显的调试残留),就应判定为 BLOCK。如对疑似机密信息存疑,倾向判定为 BLOCK。 - PASS — 仅当未发现问题,或发现的问题明显无害时,才可判定为 PASS。
格式:
**BLOCK**
或
**PASS**
切勿淡化真实机密信息泄露问题——历史记录中的密钥泄露会造成高昂的补救成本。