# 资产清单防漂移校验模式

适用于技能包、插件包、数据仓库、模板库等同时维护“实际文件树”和 `WHATS_INCLUDED.md` / manifest / README 清单的项目。

## 触发条件

- 新增、删除或重命名 `scripts/`、`templates/`、`assets/` 下的文件。
- 人工清单声称“已包含全部脚本/模板”。
- CI 已有结构校验，但没有覆盖“清单是否与文件树一致”。

## 推荐校验器设计

1. **只解析 canonical 区段**
   - 例如只解析 `## 可运行脚本` 表，而不是全文件搜索 ``scripts/*.py``。
   - 避免模板区、说明文字、历史备注里的顺手提及污染结果。

2. **用精确键匹配**
   - 对技能脚本使用 `(skill_slug, script_name)`。
   - 对模板/资产可用 `(owner_dir, relative_path)`。
   - 不要只用 basename；同名文件或错挂技能会假通过。

3. **同时检查三类漂移**
   - 缺失：文件存在但清单无行。
   - 陈旧：清单有行但文件已不存在。
   - 重复：同一精确键出现多次。

4. **结构化检测入口**
   - Python 脚本入口用 AST 检测真实 `if __name__ == "__main__"`。
   - 不要只搜 `__main__` 字符串；注释/docstring 会误报。

5. **分阶段收紧质量门**
   - 第一阶段：缺登记/不可编译/无真实入口 hard fail；selftest 缺口 warning。
   - 第二阶段：补齐 selftest 后立刻把 selftest 覆盖转为 hard fail，避免后续新增脚本只登记不自测。
   - 第三阶段（可选）：CI 不只检查 selftest marker，还按成本分层实际运行 `--selftest`：stdlib/纯函数脚本每次跑，重依赖/慢图形脚本可定时或矩阵跑。

6. **自测入口设计**
   - 入口统一用显式 `--selftest`（可保留历史 `--self-test` alias），不要靠“无参数 demo”冒充自测。
   - 自测使用合成数据、临时目录、真实断言；不要依赖网络、账号、LibreOffice 等外部状态。
   - 可选依赖缺失时，断言降级路径（skip/degraded record）而不是失败；可用时再验证实际产物。

7. **CI 触发范围要包含清单本身**
   - 如果 `WHATS_INCLUDED.md` 改动不会触发 CI，校验器就无法防止清单漂移。

## 常见坑

- 全文件正则搜 ``scripts/*.py``，导致“模板配套说明”被计入可运行脚本清单。
- 用脚本文件名匹配，无法发现脚本被登记到错误技能下。
- 用字符串 `__main__` 判断入口，注释和文档也能满足。
- 一次性把所有 selftest 缺口设为 hard fail，导致治理无法增量落地；应先可观测，再逐步收紧。
