项目背景
Agent Handoff 是一个本地运行的 AI 编程项目接力包生成器,目标不是代替开发者写代码,而是把项目当前状态整理成一组可交接、可复核的 Markdown 文件,方便 Codex、Cursor、Claude Code 等 Agent 在换会话、换模型或换操作者后继续工作。
M1 完成仓库扫描,M2 完成技术栈、入口、命令和 Git 状态识别,M3 完成 TASK.md 与 HANDOFF.md。到了 M4,这个项目第一次进入一个很现实的阶段:接力包越完整,越可能把敏感信息也一起带出去。
当前版本:0.4.0。
1. M4 要解决的不是"多生成一个文件",而是默认安全边界
M3 之前,Agent Handoff 已经能输出:
text
.agent-handoff/
├── HANDOFF.md
├── REPO_MAP.md
├── TASK.md
├── COMMANDS.md
├── GIT_STATE.md
└── manifest.json
这套输出足够让下一个 Agent 快速了解项目,但也带来一个问题:如果命令、任务说明、Git 信息和路径本身含有敏感内容,接力包会把这些信息集中暴露出来。
因此 M4 的重点不是功能堆叠,而是安全收口:
- 默认敏感路径脱敏;
- 默认内容扫描;
- 结构化字段统一脱敏;
- 生成可复核的
REDACTION.md; - 用真实项目验证,而不是只看单元测试。
2. 路径脱敏:先把明显危险的文件挡在外面
M4 默认覆盖一批常见敏感规则,包括:
.env、.env.**.pem、*.key、*.p12、*.pfxcredentials.*secrets.**.token*secret**credential*.npmrc.git-credentials
这类规则在扫描后执行,优先级高于 include,也就是说即使用户在配置里尝试恢复文件,命中敏感规则的路径仍然会被排除。
项目也支持在 .agent-handoff.json 里追加自定义规则:
json
{
"redact": ["secrets/", "private/", "*.token"]
}
这里比较关键的一个修复点是:目录规则命中后,整个后代树都会被移除,不能只匹配目录名本身,更不能被 include 再捞回来。
3. 内容扫描和字段级脱敏:必须保留的证据文件不能直接丢
只做路径脱敏并不够,原因很简单:像 package.json、任务文件、Git 提交信息这些内容,既可能包含敏感信息,又是识别项目状态必须保留的证据。
例如下面这种脚本:
json
{
"scripts": {
"start": "API_KEY=secret-value node src/index.js"
}
}
package.json 不能因为含敏就整个删除,否则 Node.js 技术栈和运行命令都识别不出来。M4 的处理方式是:
- 普通文本文件默认执行内容扫描;
- 命中敏感模式的普通文件直接从接力包中排除;
- 对必须保留的结构化字段执行字段级脱敏,再写入
HANDOFF.md、COMMANDS.md、GIT_STATE.md和manifest.json。
当前字段级脱敏覆盖的对象包括:
- 命令与脚本;
- 任务解析结果;
- Git 状态与提交信息;
- manifest;
REDACTION.md里的自定义规则展示。

4. 这次真正难的点:秘密格式不统一
M4 过程中踩到的一个典型问题是,程序一开始能识别字符串中的 apiKey=...,但识别不了对象字段里的普通字符串值:
json
{
"apiKey": "plain-secret-value"
}
原因不是正则没写,而是早期逻辑只看 value,不看 key 的语义。value 本身没有固定前缀,看起来就像普通字符串。
后续修复把字段名识别扩展成了更完整的后缀匹配和归一化流程,统一处理:
- 驼峰命名;
- 下划线命名;
- 连字符命名;
- 带供应商或业务前缀的字段。
例如:
apiKeyapi_keyapi-keygithubTokendatabasePasswordaws_secret_access_key
与此同时,测试里保留了 username、databaseName、homepage 等非敏感字段,避免误伤过大。
5. 路径本身也可能泄密
除了内容,路径也是 M4 后半段的重点。
最开始只处理了文件内容,后来发现这些位置也会暴露信息:
- 报告中的项目根目录绝对路径;
- 文件名和目录名中的 Token 片段;
- 项目显示名;
- 扩展名统计;
- manifest 中的派生字段;
- CLI 成功输出的本机绝对路径。
后续统一调整为:
manifest.projectRoot只记录项目名,不记录绝对路径;- 文档内部只保留项目内相对路径;
- 用户主目录统一显示为
$HOME; - 项目显示名、统计字段、忽略记录、路径段都走同一套脱敏逻辑;
- CLI 成功输出只显示
.agent-handoff/<file>相对路径。
其中一个值得注意的实现变化是:manifest.stats.byExtension 改成数组形式,而不是把用户可控的扩展名直接当作对象键。
6. M4 新增 REDACTION.md
这一版新增的 REDACTION.md 不是一句"已处理",而是一份可复核记录,主要包含:
- 默认脱敏规则;
- 自定义脱敏规则;
- 本次被排除的路径及命中规则;
- 内容保护说明。
它不会回显秘密原文,路径本身也会再次脱敏。这个文件的作用不是证明"绝对安全",而是让交接包多一层可审查证据。
7. 端到端测试和真实项目验证
M4 最后通过的不是几条函数用例,而是完整流程验证。
当前自动化结果:
bash
npm test
结果为:78 项通过,0 失败。
覆盖内容包括:
- 默认脱敏与自定义脱敏;
- 内容检测;
- 字段级脱敏;
- 任务文件泄露绕路;
- 权限不足;
- 超大文件;
- 符号链接;
- 非 Git 项目;
- CLI 端到端生成后对输出文件再次扫描。
真实项目验证则用了 2 个项目:
- Agent Handoff 自身的 Node.js 项目;
- 一个真实 Java/Maven Git 仓库
flink_tcms_data_disptach。
第二个项目的验证结果有两个点值得保留:
- Git 分支与工作区状态采集正常;
- 由于当前版本只识别 Node.js、Python、Go、Rust,Java 会如实标记为"技术栈未识别",不会为了让结果好看强行猜测。
8. 已知边界
M4 之后,Agent Handoff 的安全边界比之前清楚很多,但它仍然不是专业密钥扫描器。
当前明确边界包括:
- 对完全没有特征、字段名也没有语义提示的普通字符串,工具无法凭空判断其是否为秘密;
- 内容扫描默认开启,但不是无限制读取,超大文件会按既有扫描规则跳过内容读取;
- 当前技术栈识别仍然只覆盖 Node.js、Python、Go、Rust;
- 工具不会修改、提交、推送或上传用户代码。
总结
M4 把 Agent Handoff 从"能交接项目"推进到"默认更安全地交接项目"。
这次最重要的收获不是新增了 REDACTION.md,而是把几个现实问题真正串起来处理了:过滤 .env 不等于命令安全,扫描字符串不等于对象字段安全,文件树干净不等于派生字段干净,单元测试通过也不等于最终交出去的七个文件没有泄露。
如果说 M3 解决的是"下一个 Agent 怎么接得上",那 M4 解决的就是"接上以后,不要顺手把项目钥匙也交出去"。
#Nodejs #AI编程 #Agent #信息安全 #Git #软件工程