跳转至

SOP · 备份清理评估 与 收尾软提醒

主题:backup-hygiene-20261011 日期:2026-10-11 类型:C 类变更(改脚本 + 改 hook + 新增技能 + 改规则)

1. 背景

两件事都要「把人工推动变成机制」:

  • 收尾自查此前无 hook 兜底:它是我每轮主动跑 cost_audit/wrapup.py 的产物,全靠 rule + skill 文本口径,漏做即静默(用户反馈「好几轮没见收尾」)。根因是 SKILL.md 曾限定「多步执行类」,与 rule 的 10-10 口径「每轮必出、不区分任务类型」冲突——已修口径,但仍没有任何硬保障。
  • 备份清理无机械判据:*/backup/ 已累积 86 个主题目录 / 440 个 .bak / 约 22 MB。全局规则《备份与留档》规定「变更验证通过后由用户对照 README.md 自行删除、Agent 不主动删除」,但「哪些算验证通过」没有可执行判据,只能人工逐个看。

2. 目标

  • 收尾自查加软提醒:同一会话累计步数达阈仍未见 wrapup.py → 提醒一次(不阻断)。
  • 备份清理加评估工具:docgen/backup_ledger.py --prune 按「双 3 天」判据列出可删备份,默认只报告。
  • 新增技能 backup-hygiene 承载清理流程;规则《备份与留档》§清理加一行指针、技能索引登记该技能。

3. 前置条件

  • python3;执行 --prune 时 cwd = token_proxy 根(默认扫描根 = cwd 与 ~/.trae-cn)。
  • 本次未改 hooks.json,无「重启 Trae」要求;只改 hook 脚本内容,下次工具调用即生效。

4. 影响范围

  • 单机、无需停服、无窗口期要求。
  • 触及文件:
  • docgen/backup_ledger.py(新增 --prune/--delete/--days/--root/-v,新增 4 函数 + 自测)
  • merge-guard/merge-guard.py(新增判据 W + 常量 + 文案 + 状态字段)
  • ~/.trae-cn/skills/backup-hygiene/SKILL.md(新建)
  • ~/.trae-cn/user_rules/rule-ops-evidence-constraints.md、rule-skill-index.md(各一行)
  • merge-guard 挂 PreToolUse matcher:*,改动对所有工具的调用即时生效。

5. 分步操作

步骤 1:扩展 docgen/backup_ledger.py(新增清理评估)

在既有「台账生成 / 变更脚手架」之上加 --prune 评估模式,复用其扫描与路径解析,不另起炉灶。

注意事项与坑: - 备份年龄取文件名时间戳、不取 mtime:do_backup() 用 shutil.copy2(保留 mtime),而部分备份是普通 cp(mtime = 复制时刻),mtime 口径不一致;只有 <原名>.bak.<YYYYmmdd-HHmmss> 里的时间戳权威。 - 脚本自身不主动删:默认只报告;真删需 --delete 显式授权(承接规则「Agent 不主动删除」)。 - 源路径解析含两个转义前缀(trae-cn/ → ~/.trae-cn/、home/ → 绝对路径)与 +.md 回退(覆盖 user_rules/backup 剥掉 .md 的例外);解析不出一律记「需人工」、不动。 - 备份按 backup/<原路径层次>/... 存放,评估时须向上找最近的 backup/ 祖先作为备份根(首版只扫 backup/ 直属文件、漏了子目录,已修)。

cd ~/Documents/services/token_proxy
python3 -m py_compile docgen/backup_ledger.py        # 预期 rc=0
python3 docgen/backup_ledger.py --selftest           # 预期 ... selftest PASS
python3 docgen/backup_ledger.py --prune              # 预期 只报告,不删任何文件

预期:--prune 打印「扫描 .bak:N | 可删:N | 保留:N | 需人工:N」与可删清单,全程不写不删。 失败判断:selftest FAIL → 判据逻辑有误,检查 prune();输出 0 条但显存备份 → 检查是否漏扫子目录。

步骤 2:给 merge-guard/merge-guard.py 加判据 W(收尾软提醒)

注意事项与坑: - W 独立注入、不占 INJECT_MAX(与 P/Q 同型),否则会被其它提醒挤掉。 - 每「收尾周期」至多提醒一次:w_fired 置真后不再重复;跑过 wrapup.py 即清零复位(靠命令里匹配 wrapup.py)。 - 阈值 WRAPUP_STEP_NUDGE = 15:高于日常单轮步数(实测多在 5~8 步),只兜「长轮次 / 跨轮漂移」。 - 判据只提醒不阻断:ENFORCE_MARKS 仍为空,emit() 走 permissionDecision: allow。

cd ~/Documents/services/token_proxy
python3 -m py_compile merge-guard/merge-guard.py     # 预期 rc=0
# 行为验证:连打 14 步不提醒、第 15 步提醒一次、第 16 步不重复、跑 wrapup 后 14 步不提醒
python3 backup-hygiene-20261011/verify_judge_w.py

预期:四行判定全为 True/False 序列符合「前14 False / 第15 True / 第16 False / 复位后 False」。 失败判断:第 15 步未触发 → 检查 wrapup_steps 累加与阈值;重复触发 → 检查 w_fired 是否落盘。

步骤 3:新建技能与规则指针

注意事项与坑: - 技能落全局目录 ~/.trae-cn/skills/backup-hygiene/(与既有技能一致),name 须等于目录名。 - 技能只写「清理流程」,约定仍以规则《备份与留档》为单一源,避免两处漂移。 - 规则只加一行指针(清理行 + 技能索引行),不复述细节。

ls ~/.trae-cn/skills/backup-hygiene/SKILL.md          # 预期 文件存在
python3 -c "import re,sys; t=open('$HOME/.trae-cn/skills/backup-hygiene/SKILL.md',encoding='utf-8').read(); print('frontmatter_ok' if t.startswith('---') and 'name: backup-hygiene' in t else 'BAD')"

6. 验证

cd ~/Documents/services/token_proxy
python3 -m py_compile docgen/backup_ledger.py merge-guard/merge-guard.py   # 均 rc=0
python3 docgen/backup_ledger.py --selftest                                 # selftest PASS
python3 docgen/backup_ledger.py --prune                                    # 只报告
python3 backup-hygiene-20261011/verify_judge_w.py                          # W 行为四断言通过

实测结果(2026-10-11): - --selftest → PASS(含 prune 判据:源静默 5 天判可删、源刚改判保留)。 - --prune 实盘 → 扫描 440 | 可删 18 | 保留 266 | 需人工 156(判据天然保守)。 - 判据 W → 第 15 步触发一次、第 16 步不重复、跑过 wrapup.py 即复位(四断言全过)。

7. 回滚

备份位置:backup-hygiene-20261011/backup/,逐条登记见 backup/README.md。

回滚步骤(整文件覆盖式改动,逐名 cp -p 回原路径):

cd ~/Documents/services/token_proxy
TS=20261011-163350
cp -p backup-hygiene-20261011/backup/docgen/backup_ledger.py.bak.$TS docgen/backup_ledger.py
cp -p backup-hygiene-20261011/backup/merge-guard/merge-guard.py.bak.$TS merge-guard/merge-guard.py
cp -p backup-hygiene-20261011/backup/trae-cn/user_rules/rule-ops-evidence-constraints.md.bak.$TS ~/.trae-cn/user_rules/rule-ops-evidence-constraints.md
cp -p backup-hygiene-20261011/backup/trae-cn/user_rules/rule-skill-index.md.bak.$TS ~/.trae-cn/user_rules/rule-skill-index.md
rm -rf ~/.trae-cn/skills/backup-hygiene        # 新建技能,回滚即移除

特殊说明:两个 .py 的备份是改后补备份——本工程非 git 仓库、且改动发生在备份之前,无法 cp 到原文。改用 rebuild_prechange_backups.py 由当前文件反向剥离本次改动块重建原文(替换前逐块断言存在,未产出错误备份),重建结果已 py_compile 通过。

回滚后验证:

python3 -m py_compile docgen/backup_ledger.py merge-guard/merge-guard.py
python3 docgen/backup_ledger.py --prune          # 预期报 未知参数 → 已回滚
python3 backup-hygiene-20261011/verify_judge_w.py  # 预期 第15步不再出现【收尾提醒】

8. 风险说明

风险 缓解
W 阈值 15 会在「正常长任务尚未收尾」时提醒一次 提醒极短、每收尾周期至多一次;阈值高于日常单轮步数 5~8
--prune 源路径解析不出(旧格式 / 平铺) 记「需人工」、不删;解析不出不影响其它项
--delete 误删 默认关闭、需显式授权;判据要求源已静默 ≥3 天,稳健
hook 脚本异常 main() 外层 except Exception: pass + exit 0 兜底不变,绝不影响工具调用

附录 · 交付物与回滚点

交付物 路径 说明
备份清理评估 docgen/backup_ledger.py --prune(新增模式) 复用既有扫描器;默认只报告
收尾软提醒 merge-guard/merge-guard.py 判据 W 仅提醒、每周期一次
技能 ~/.trae-cn/skills/backup-hygiene/SKILL.md 清理流程;约定仍以规则为单一源
规则指针 rule-ops-evidence-constraints.md §清理、rule-skill-index.md 各一行
回滚重建脚本 backup-hygiene-20261011/rebuild_prechange_backups.py 反向剥离重建改动前原文
行为验证脚本 backup-hygiene-20261011/verify_judge_w.py 判据 W 四断言

来源:/home/rain/Documents/services/token_proxy/backup-hygiene-20261011/SOP.md | 最后更新:2026-10-11 16:35(由 build/sync.py 同步,请勿在站点侧修改)