SOP:HANDOFF「落点核验前置」流程 v7 + PreToolUse 写前守卫¶
主题目录:handoff-landing-20261008/|执行时间:2026-10-08|类型:C 类变更(改全局规则 / skill / Hook 脚本 / hooks.json)
1. 背景¶
docs/HANDOFF.md 长期"该落的没落":本轮已完结的内容留在 HANDOFF 里,文件逐轮上涨。2026-10-08 实测证据:
- §2「轮次概览」2 211 B(占全文 25%)一直滞留,直到文件涨到 8 812 B 才发现——而它属 skill
writing-handoff《严禁留在 HANDOFF》清单第一条。 - 根因有两条:
- 规则把触发点盖掉了:常驻规则
rule-agent-efficiency.md的《HANDOFF 容量与落点》写明「未触发时不提(HANDOFF < 11.5 KB 且未满 5 轮 → 完全不出现)」,而 skill 里写的是「本轮动过 HANDOFF 时收尾执行」落点自检。规则常驻、skill 按需加载 → 冲突时按规则走,"该落就落"被降级为"越线才做"。 - 顺序错了:旧《写入前置流程》是
①判容量 →(仅越线)②搬移 → ③写。7 KB 常态下容量判为"可直接写","落"这一步压根不执行。
用户诉求(原话):「当已有的时候,在需要写 handoff 时先核验一遍该落未落的点,有未落的执行完落动作,再开始本轮的 handoff 任务;理论上 handoff 应该一直在 7k 左右,设置 16K 是为了真有未完成项比较多的真实需求时有余量」。
2. 目标¶
变更后应达到的可验证状态:
- 写 HANDOFF 前置三步,顺序不可颠倒:① 落点核验 + 落(无条件)→ ② 量 + 判 → ③ 才写入 → ④ 复核。
- 三档水位语义:
≈7 KB常态化健康水位|≥ 9 KB偏高 → 先查「该落未落」,不是压缩|≥ 14.5 KB先整体重写|16 KB硬余量。 - 写 HANDOFF 必被提醒一次(每会话一次,PreToolUse 写前注入),不再依赖用户人工推动。
3. 前置条件¶
~/.trae-cn/可写(已由permission-grant-20261008授权readWrite: ["/tmp", "/home/rain"])。python3(仅标准库依赖)。- 重启 Trae:
hooks.json新增挂载在启动时读取,本会话不生效。 - 执行前检查:
bash test -w ~/.trae-cn/user_rules/rule-agent-efficiency.md && echo "规则可写" test -w ~/.trae-cn/hooks.json && echo "hooks.json 可写" python3 -c "import json;json.load(open('$HOME/.trae-cn/hooks.json'));print('hooks.json 合法')"
4. 影响范围¶
| 项 | 内容 |
|---|---|
| 主机 | 本机 dell-R620(单机,无冗余) |
| 受影响对象 | ① 全局规则 rule-agent-efficiency.md(所有会话每步重放);② 全局 skill writing-handoff(按需加载);③ cost_audit/handoff_precheck.py(写入前置取数);④ hooks.json 新增 1 条 PreToolUse 挂载(全局所有会话) |
| 是否需停服 | 否。不影响 token_proxy 代理进程(ds/glm/mi) |
| 在跑作业 | 无。本次不改 proxy.py / config.yaml |
| 窗口期 | 无限制;唯一约束是重启 Trae 会中断当前会话 |
5. 分步操作¶
步骤 1:备份(高危前置,不可省)¶
先把 5 个待改文件按 <原名>.bak.<YYYYmmdd-HHMMSS> 复制到本主题 backup/ 下,目录层次保留原路径。
TS=$(date +%Y%m%d-%H%M%S)
D=/home/rain/Documents/services/token_proxy/handoff-landing-20261008/backup
mkdir -p "$D/trae-cn/user_rules" "$D/trae-cn/skills/writing-handoff" \
"$D/token_proxy/cost_audit" "$D/token_proxy/rule-acceptance-20261008"
cp -p ~/.trae-cn/user_rules/rule-agent-efficiency.md "$D/trae-cn/user_rules/rule-agent-efficiency.md.bak.$TS"
cp -p ~/.trae-cn/skills/writing-handoff/SKILL.md "$D/trae-cn/skills/writing-handoff/SKILL.md.bak.$TS"
cp -p ~/.trae-cn/hooks.json "$D/trae-cn/hooks.json.bak.$TS"
cp -p /home/rain/Documents/services/token_proxy/cost_audit/handoff_precheck.py \
"$D/token_proxy/cost_audit/handoff_precheck.py.bak.$TS"
cp -p /home/rain/Documents/services/token_proxy/rule-acceptance-20261008/offline_verify_handoff_precheck.py \
"$D/token_proxy/rule-acceptance-20261008/offline_verify_handoff_precheck.py.bak.$TS"
echo "TS=$TS"
预期:TS=20261008-151534,find "$D" -type f 列出 5 个文件。
失败判断:任一 cp 报错(权限 / 路径)→ 停止,不得继续改动。
步骤 2:改全局规则(A′+C 的规则侧)¶
替换 ~/.trae-cn/user_rules/rule-agent-efficiency.md 中《HANDOFF 容量与落点》整节:写入前置改三步(落点核验在最前)、补三档水位语义、删去「未触发时不提」。
坑:这节与 skill 正文必须同时改。只改一处会出现"两处口径打架",2026-10-08 曾因口径不一致(规则 11776 / 脚本 12288)读错数字、返工一次。
步骤 3:改 skill writing-handoff(A′+C 的规范侧,共 4 处)¶
| # | 位置 | 改动 |
|---|---|---|
| 1 | 《长度预算》 | 换成三档语义(7 健康 / 9 偏高 / 14.5 动作线 / 16 上限) |
| 2 | 《何时重写》表 | 「7~14.5 正常运行区 不报」→ 「≈7 KB 常态」+「≥9 KB 先查落点」+「9~14.5 查过后仍在则保留」 |
| 3 | 《写入前置流程》 | v6 → v7:新增「① 落点核验 + 落」并置于最前;② 量判含「≥9 KB 回第 ① 步」 |
| 4 | 《收尾检查清单》 | 旧数 ≤ 12288 / ≥11776 → ≤ 16384,并写明"先做落点核验" |
同时修 3 处旧口径残留:PROJECT-MAP 对比表「长度」行、《为什么用滞回》段、《≥5 轮》段(11.5 KB → 14.5 KB)。
步骤 4:改取数脚本 cost_audit/handoff_precheck.py(A′ 的判据侧)¶
verdict() 由两档改三档,并新增常量:
WARN_BYTES = 9 * 1024 # 9216 偏高线:≥ 它先查落点,不压缩(v7 新增)
HEALTHY_KB = 7 # 健康水位(仅用于文案)
主输出顶部追加一行「第一步(先做):逐行过入口三问……」。坑:这一行是"写前触发"的实际载体——正常路径下模型先跑本脚本,看到该行即想起先落。
步骤 5:新增 PreToolUse 写前守卫(B′)¶
新建 handoff-landing-guard/handoff-landing-guard.py:认「写类工具(Write/Edit/SearchReplace/MultiEdit/NotebookEdit)+ docs/HANDOFF.md」,PreToolUse 注入落点提醒(allow + additionalContext,绝不 deny);去重键 (session_id),缺 session_id 时不去重(漏注入 > 重复注入)。
坑:PreToolUse 退出码 2 等价 deny,一次误判就废掉本轮写入——故任何异常路径必须静默 exit 0;提示文本进入上下文后每轮重放,必须短。
挂载到 ~/.trae-cn/hooks.json 的 PreToolUse 数组(matcher: "*"):
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "s=\"$HOME/Documents/services/token_proxy/handoff-landing-guard/handoff-landing-guard.py\"; [ -f \"$s\" ] && python3 \"$s\" || true; exit 0",
"timeout": 10
}
]
}
校准:json.load 校验 + 数挂载数(预期 PreToolUse 8 → 9,总数 13 → 14)。
python3 -c "import json;d=json.load(open('$HOME/.trae-cn/hooks.json'));print({k:len(v) for k,v in d['hooks'].items()},'total',sum(len(v) for v in d['hooks'].values()))"
步骤 6:重启 Trae¶
hooks.json 在启动时读取——不重启则新 Hook 不生效(多次实测:改 hook 脚本同会话下一次请求即生效;改 hooks.json 增删挂载须重启)。
6. 验证¶
| # | 判据 | 命令 | 期望 |
|---|---|---|---|
| V1 | 取数脚本三档正确 | python3 rule-acceptance-20261008/offline_verify_handoff_precheck.py |
末行 全部通过(含 U8b 偏高线 / U9c 反例 / E2 v7 文案) |
| V2 | 新 Hook 正反例 | python3 rule-acceptance-20261008/offline_verify_handoff_landing_guard.py |
末行 全部通过(1 正例 / 5 反例 / 5 单元) |
| V3 | hooks.json 合法且挂载数正确 |
见步骤 5 校准命令 | PreToolUse: 9,total 14 |
| V4 | 语法编译 | python3 -m py_compile cost_audit/handoff_precheck.py handoff-landing-guard/handoff-landing-guard.py |
无输出、rc=0 |
| V5 | 真机单跑注入 | echo '{"tool_name":"Edit","tool_input":{"file_path":"/tmp/probe/docs/HANDOFF.md"},"session_id":"probe-01"}' \| python3 handoff-landing-guard/handoff-landing-guard.py |
输出含 【HANDOFF 落点前置】… 与 "permissionDecision": "allow" |
| V6 | 重启后真机 | 向 docs/HANDOFF.md 写入一次 |
会话内出现一次注入;再次写入不再出现(去重) |
幂等复验:V1/V2 各跑两遍,两遍结果一致。
7. 回滚¶
备份位置:handoff-landing-20261008/backup/(登记见该目录 README.md)。
TS=20261008-151534
D=/home/rain/Documents/services/token_proxy/handoff-landing-20261008/backup
cp -p "$D/trae-cn/user_rules/rule-agent-efficiency.md.bak.$TS" ~/.trae-cn/user_rules/rule-agent-efficiency.md
cp -p "$D/trae-cn/skills/writing-handoff/SKILL.md.bak.$TS" ~/.trae-cn/skills/writing-handoff/SKILL.md
cp -p "$D/trae-cn/hooks.json.bak.$TS" ~/.trae-cn/hooks.json
cp -p "$D/token_proxy/cost_audit/handoff_precheck.py.bak.$TS" \
/home/rain/Documents/services/token_proxy/cost_audit/handoff_precheck.py
cp -p "$D/token_proxy/rule-acceptance-20261008/offline_verify_handoff_precheck.py.bak.$TS" \
/home/rain/Documents/services/token_proxy/rule-acceptance-20261008/offline_verify_handoff_precheck.py
rm -rf /home/rain/Documents/services/token_proxy/handoff-landing-guard # 高危:删除新增 Hook 目录
随后重启 Trae。
回滚后验证:python3 -c "import json;json.load(open('$HOME/.trae-cn/hooks.json'))" 合法,且挂载数回到 13;rule-agent-efficiency.md 中《HANDOFF 容量与落点》为 v6 形态。
若要保留规则/skill 的新语义、只去掉 Hook:仅回滚 hooks.json 一项并重启即可(规则与 skill 不依赖 Hook 生效)。
8. 风险说明¶
| 风险 | 缓解 |
|---|---|
| 新 Hook 误注入(非 HANDOFF 文件也提示) | 触发面收窄为「写类工具 + docs/HANDOFF.md」;U3/U4/U5 三个反例覆盖(写 SOP / 只读 / 非 docs 路径均静默) |
| 新 Hook 阻断写入 | 只 allow + 注入,不 deny;异常路径静默 exit 0;hooks.json 命令行带 [ -f ] 守卫 |
| 提示文本每轮重放推高成本 | 文案压到约 170 字;每会话只注入一次(去重) |
| 规则与 skill 口径再次漂移 | 本次三处同步(规则 / skill / 脚本);offline_verify_handoff_precheck.py 的 U8b/U9c 锁死档位边界 |
| 挂载数变化后删目录漏核对 | 已写入本 SOP 与 backup/README.md;HANDOFF §4 红线的挂载数需同步为 10 脚本 / 14 挂载 |
来源:
/home/rain/Documents/services/token_proxy/handoff-landing-20261008/SOP.md| 最后更新:2026-10-08 15:20(由build/sync.py同步,请勿在站点侧修改)