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挂 PreToolUsematcher:*,改动对所有工具的调用即时生效。
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同步,请勿在站点侧修改)